Remove always defined FEATURE_CORECLR
[platform/upstream/coreclr.git] / src / debug / di / rspriv.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 //*****************************************************************************
5 // rspriv.
6 // 
7
8 //
9 // Common include file for right-side of debugger.
10 //*****************************************************************************
11
12 #ifndef RSPRIV_H
13 #define RSPRIV_H
14
15 #include <winwrap.h>
16 #include <windows.h>
17
18 #include <utilcode.h>
19
20
21 #ifdef _DEBUG
22 #define LOGGING
23 #endif
24
25 #include <log.h>
26 #include <corerror.h>
27
28 #include "cor.h"
29
30 #include "cordebug.h"
31 #include "xcordebug.h"
32 #include "cordbpriv.h"
33 #include "mscoree.h"
34
35 #include <cordbpriv.h>
36 #include <dbgipcevents.h>
37
38 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
39 #include <ipcmanagerinterface.h>
40 #endif // !FEATURE_DBGIPC_TRANSPORT_DI
41
42 #include "common.h"
43 #include "primitives.h"
44
45 #include "dacdbiinterface.h"
46
47 #include "helpers.h"
48
49 struct MachineInfo;
50
51 #include "nativepipeline.h"
52 #include "stringcopyholder.h"
53
54
55 #include "eventchannel.h"
56
57 #undef ASSERT
58 #define CRASH(x)  _ASSERTE(!x)
59 #define ASSERT(x) _ASSERTE(x)
60
61 // We want to keep the 'worst' HRESULT - if one has failed (..._E_...) & the
62 // other hasn't, take the failing one.  If they've both/neither failed, then
63 // it doesn't matter which we take.
64 // Note that this macro favors retaining the first argument
65 #define WORST_HR(hr1,hr2) (FAILED(hr1)?hr1:hr2)
66
67 // #UseDataTarget
68 // Forbid usage of OS APIs that we should be using the data-target for
69 #define ReadProcessMemory DONT_USE_READPROCESS_MEMORY
70 #define WriteProcessMemory DONT_USE_WRITEPROCESS_MEMORY
71
72
73 /* ------------------------------------------------------------------------- *
74  * Forward class declarations
75  * ------------------------------------------------------------------------- */
76
77 class CordbBase;
78 class CordbValue;
79 class CordbModule;
80 class CordbClass;
81 class CordbFunction;
82 class CordbCode;
83 class CordbFrame;
84 class CordbJITILFrame;
85 class CordbInternalFrame;
86 class CordbContext;
87 class CordbThread;
88 class CordbVariableHome;
89
90 #ifdef FEATURE_INTEROP_DEBUGGING
91 class CordbUnmanagedThread;
92 struct CordbUnmanagedEvent;
93 #endif
94
95 class CordbProcess;
96 class CordbAppDomain;
97 class CordbAssembly;
98 class CordbBreakpoint;
99 class CordbStepper;
100 class Cordb;
101 class CordbEnCSnapshot;
102 class CordbWin32EventThread;
103 class CordbRCEventThread;
104 class CordbRegisterSet;
105 class CordbNativeFrame;
106 class CordbObjectValue;
107 class CordbEnCErrorInfo;
108 class CordbEnCErrorInfoEnum;
109 class Instantiation;
110 class CordbType;
111 class CordbNativeCode;
112 class CordbILCode;
113 class CordbReJitILCode;
114 class CordbEval;
115
116 class CordbMDA;
117
118 class CorpubPublish;
119 class CorpubProcess;
120 class CorpubAppDomain;
121 class CorpubProcessEnum;
122 class CorpubAppDomainEnum;
123
124
125 class RSLock;
126 class NeuterList;
127
128 class IDacDbiInterface;
129
130 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
131 class DbgTransportTarget;
132 class DbgTransportSession;
133 #endif // FEATURE_DBGIPC_TRANSPORT_DI
134
135 // @dbgtodo  private shim hook - the RS has private hooks into the shim to help bridge the V2/V3 gap. 
136 // This helps provide a working dogfooding story throughout our transition.
137 // These hooks must be removed before shipping.
138 class ShimProcess;
139
140
141 #ifndef FEATURE_PAL
142 extern HINSTANCE GetModuleInst();
143 #endif
144
145
146 template <class T>
147 class CordbSafeHashTable;
148
149
150 //---------------------------------------------------------------------------------------
151 //
152 // This is an encapsulation of the information necessary to connect to the debugger proxy on a remote machine. 
153 // It includes the IP address and the port number.  The IP address can be set via the env var 
154 // COMPlus_DbgTransportProxyAddress, and the port number is fixed when Mac debugging is configured.
155 //    
156
157 struct MachineInfo
158 {
159 public:
160     void Init(DWORD dwIPAddress, USHORT usPort)
161     {
162         m_dwIPAddress = dwIPAddress;
163         m_usPort      = usPort;
164     }
165
166     void Clear()
167     {
168         m_dwIPAddress = 0;
169         m_usPort      = 0;
170     }
171
172     DWORD  GetIPAddress() {return m_dwIPAddress;};
173     USHORT GetPort() {return m_usPort;};
174
175 private:
176     DWORD  m_dwIPAddress;
177     USHORT m_usPort;
178 };
179
180 extern forDbiWorker forDbi;
181
182 // for dbi we just default to new, but we need to have these defined for both dac and dbi
183 inline void * operator new(size_t lenBytes, const forDbiWorker &)
184 {
185     void * result = new BYTE[lenBytes];
186     if (result == NULL) 
187     {
188         ThrowOutOfMemory();
189     }
190     return result;
191 }
192
193 inline void * operator new[](size_t lenBytes, const forDbiWorker &)
194 {
195     void * result = new BYTE[lenBytes];
196     if (result == NULL) 
197     {
198         ThrowOutOfMemory();
199     }
200     return result;
201 }
202
203 // Helper to delete memory used with the IDacDbiInterface::IAllocator  interface.
204 template<class T> inline
205 void DeleteDbiMemory(T *p)
206 {
207     delete p;
208 }
209
210
211
212 //---------------------------------------------------------------------------------------
213 //
214 // Simple array of holders (either RSSmartPtrs or RSExtSmartPtrs).
215 // Holds a reference to each element.
216 //
217 // Notes:
218 //    T is the base type and HOLDER_T is the type of the holder.  All functions implemented on this base
219 //    class must work for both RSSmartPtrs and RSExtSmartPtrs.  For example, there is no concept of neutering
220 //    for RSExtSmartPtrs.
221 //
222
223 template<typename T, typename HOLDER_T>
224 class BaseRSPtrArray
225 {
226 public:
227     BaseRSPtrArray()
228     {
229         m_pArray = NULL;
230         m_cElements = 0;
231     }
232
233     // Is the array emtpy? 
234     bool IsEmpty() const
235     {
236         return (m_pArray == NULL);
237     }
238
239     // Allocate an array of ptrs.
240     // Returns false if not enough memory; else true.
241     bool Alloc(unsigned int cElements)
242     {
243         // Caller should have already Neutered
244         _ASSERTE(IsEmpty());
245
246         // It's legal to allocate 0 items. We'll succeed the allocation, but still claim that IsEmpty() == true.
247         if (cElements == 0)
248         {
249             return true;
250         }
251
252         // RSSmartPtr ctor will ensure all elements are null initialized.
253         m_pArray = new (nothrow) HOLDER_T [cElements];
254         if (m_pArray == NULL)
255         {
256             return false;
257         }
258
259         m_cElements = cElements;
260         return true;
261     }
262
263     // Allocate an array of ptrs.
264     // Throw on failure
265     void AllocOrThrow(unsigned int cElements)
266     {
267         if (!Alloc(cElements))
268         {
269             ThrowOutOfMemory();
270         }
271     }
272
273     // Release each element and empty the array.
274     void Clear()
275     {
276         // this Invoke dtors on each element which will release each element
277         delete [] m_pArray;
278
279         m_pArray = NULL;
280         m_cElements = 0;
281     }
282
283     // Array lookup. Caller gaurantees this is in range.
284     // Used for reading
285     T* operator [] (unsigned int index) const
286     {
287         _ASSERTE(m_pArray != NULL);
288         CONSISTENCY_CHECK_MSGF((index <= m_cElements), ("Index out of range. Index=%u, Max=%u\n", index, m_cElements));
289         
290         return m_pArray[index];
291     }
292
293     // Assign a given index to the given value. The array holder will increment the internal reference on the value.
294     void Assign(unsigned int index, T* pValue)
295     {
296         _ASSERTE(m_pArray != NULL);
297         CONSISTENCY_CHECK_MSGF((index <= m_cElements), ("Index out of range. Index=%u, Max=%u\n", index, m_cElements));
298         
299         m_pArray[index].Assign(pValue);
300     }
301
302     // Get lenght of array in elements.
303     unsigned int Length() const
304     {
305         return m_cElements;
306     }
307
308     // Some things need to get the address of an element in the table.
309     // For example, CordbThreads have an array of CordbFrame objects, and then CordbChains describe a range
310     // or frames via pointers into the CordbThread's array.
311     // This is a dangerous operation because it lets us side-step reference counting and protection.
312     T ** UnsafeGetAddrOfIndex(unsigned int index)
313     {
314         return m_pArray[index].UnsafeGetAddr();
315     }
316
317 protected:
318     // Raw array of values. 
319     HOLDER_T * m_pArray;
320
321     // Number of elements in m_pArray. Note the following is always true: (m_cElements == 0) == (m_pArray == NULL);
322     unsigned int m_cElements; 
323 };
324
325
326 //-----------------------------------------------------------------------------
327 //
328 // Simple array holder of RSSmartPtrs (internal pointers).
329 // Holds a reference to each element.
330 //
331 // Notes:
332 //    This derived class adds the concept of neutering to the base pointer array.
333 //    Allows automatic Clear()ing; do not use this unless it is safe to do so in
334 //    all cases - e.g. you're holding a local.
335 //
336
337 template< typename T, typename HOLDER_T = RSSmartPtr<T> >   // We need to use HOLDER_T to make gcc happy.
338 class RSPtrArray : public BaseRSPtrArray<T, HOLDER_T>
339 {
340 private:
341     typedef BaseRSPtrArray<T, HOLDER_T> Super;
342     BOOL m_autoClear;
343
344 public:
345     RSPtrArray() : m_autoClear(FALSE)
346     {
347     }
348     
349     ~RSPtrArray()
350     {
351         if (m_autoClear)
352         {
353             Super::Clear();
354         }
355         else
356         {
357             // Caller should have already Neutered
358             _ASSERTE(Super::IsEmpty());
359         }
360     }
361
362     void EnableAutoClear()
363     {
364         m_autoClear = TRUE;
365     }
366
367     // Neuter all elements in the array.
368     void NeuterAndClear()
369     {
370         for(unsigned int i = 0; i < Super::m_cElements; i++)
371         {
372             if (Super::m_pArray[i] != NULL)
373             {
374                 Super::m_pArray[i]->Neuter();
375             }
376         }
377
378         Super::Clear();
379     }
380 };
381
382
383 //-----------------------------------------------------------------------------
384 //
385 // Simple array holder of RSExtSmartPtrs (external pointers).
386 // Holds a reference to each element.
387 //
388 // Notes:
389 //    This derived class clears the array in its destructor.
390 //
391
392 template< typename T, typename HOLDER_T = RSExtSmartPtr<T> >    // We need to use HOLDER_T to make gcc happy.
393 class RSExtPtrArray : public BaseRSPtrArray<T, HOLDER_T>
394 {
395 private:
396     typedef BaseRSPtrArray<T, HOLDER_T> Super;
397
398 public:
399     ~RSExtPtrArray()
400     {
401         Super::Clear();
402     }
403 };
404
405
406
407 //-----------------------------------------------------------------------------
408 // Table for RSptrs
409 // This lets us map cookies <--> RSPTR_*,
410 // Then we just put the cookie in the IPC block instead of the raw RSPTR.
411 // This will also adjust the internal-reference count on the T* object.
412 // This isolates the RS from bugs in the LS.
413 // We templatize by type for type safety.
414 // Caller must syncrhonize all access (preferably w/ the stop-go lock).
415 //-----------------------------------------------------------------------------
416 template <class T>
417 class RsPtrTable
418 {
419 public:
420     RsPtrTable()
421     {
422         m_pTable = NULL;
423         m_cEntries = 0;
424     }
425     ~RsPtrTable()
426     {        
427         Clear();
428     }
429     void Clear()
430     {
431         for(UINT i = 0; i < m_cEntries; i++)
432         {
433             if (m_pTable[i])
434             {
435                 m_pTable[i]->InternalRelease();
436             }
437         }
438         delete [] m_pTable;
439         m_pTable = NULL;
440         m_cEntries = 0;
441     }
442
443     // Add a value into table.  Value can't be NULL.
444     // Returns 0 on failure (such as oom),
445     // Returns a non-zero cookie on success.
446     UINT Add(T* pValue)
447     {
448         _ASSERTE(pValue != NULL);
449         // skip 0 because it's an invalid handle.
450         for(UINT i = 1; ; i++)
451         {
452             // If we've run out of space, allocate new space
453             if( i >= m_cEntries ) 
454             {
455                 if( !Grow() )
456                 {
457                     return 0;   // failed to grow
458                 }
459                 _ASSERTE( i < m_cEntries );
460                 _ASSERTE( m_pTable[i] == NULL );
461                 // Since we grew, the next slot should now be open.
462             }
463             
464             if (m_pTable[i] == NULL)
465             {
466                 m_pTable[i] = pValue;
467                 pValue->InternalAddRef();
468                 return i;
469             }
470         }
471         UNREACHABLE();      
472     }
473
474     // Lookup the value based off the cookie, which was obtained via "Add".
475     // return NULL on error. 
476     T* Lookup(UINT cookie)
477     {
478         _ASSERTE(cookie != 0);
479         if (cookie >= m_cEntries) 
480         {
481             CONSISTENCY_CHECK_MSGF(false, ("Cookie out of range.Cookie=0x%x. Size=0x%x.\n", cookie, m_cEntries));
482             return NULL;
483         }
484         T*  p = m_pTable[cookie];
485         if (p == NULL) 
486         {   
487             CONSISTENCY_CHECK_MSGF(false, ("Cookie is for empty slot.Cookie=0x%x.\n", cookie));
488             return NULL; // empty!
489         }
490         return p;
491     }
492
493     T* LookupAndRemove(UINT cookie)
494     {
495         _ASSERTE(cookie != 0);
496         T* p  = Lookup(cookie);
497         if (p != NULL)
498         {
499             m_pTable[cookie] = NULL;
500             p->InternalRelease();
501         }
502         return p;
503     }
504
505 protected:
506     // Resize the m_pTable array.
507     bool Grow()
508     {
509         if (m_pTable == NULL)
510         {
511             _ASSERTE(m_cEntries == 0);
512             size_t cSize = 10;
513             m_pTable = new (nothrow) T*[cSize];
514             if (m_pTable == NULL)
515             {
516                 return false;
517             }
518             m_cEntries = cSize;
519             ZeroMemory(m_pTable, sizeof(T*) * m_cEntries);
520             return true;
521         }
522         size_t cNewSize = (m_cEntries * 3 / 2) + 1;
523         _ASSERTE(cNewSize > m_cEntries);
524         T** p = new (nothrow) T*[cNewSize];
525         if (p == NULL) 
526         {
527             return false;
528         }
529         ZeroMemory(p, sizeof(T*) * cNewSize);        
530
531
532         // Copy over old stuff
533         memcpy(p, m_pTable, sizeof(T*) * m_cEntries);
534         delete [] m_pTable;        
535
536         m_pTable = p;
537         m_cEntries = cNewSize;
538         return true;        
539     }
540     
541     T** m_pTable;
542     size_t m_cEntries;    
543 };
544
545
546
547 //-----------------------------------------------------------------------------
548 // Simple Holder for RS object intialization to cooperate with Neutering 
549 // semantics. 
550 // The ctor will do an addref. 
551 // The dtor (invoked in exception) will neuter and release the object. This
552 // release will likely be the final release to cause a delete.
553 // If the object is created successfully, caller should do a SuppressRelease()
554 // to avoid it getting neutered.
555 //
556 // Example: 
557 //    RSInitHolder<CordbFoo> pFoo(new CordbFoo(x,y,z));
558 //    pFoo->InitMore(a,b,c);
559 //    GiveOwnershipToSomebodyElse(pFoo); // now somebody else owns and will clean up
560 //    pFoo.ClearAndMarkDontNeuter();  // we no longer need to
561 //    
562 // So if an exception is thrown before ClearAndMarkDontNeuter(), the dtor is invoked
563 // and the object is properly destroyed (deleted and neutered). 
564 //
565 // Another common pattern is when initializing an object to hand off to an external:
566 //    RSInitHolder<CordbFoo> pFoo(new CordbFoo(x,y,z));
567 //    pFoo->InitMore(a,b,c);
568 //    pFoo.TransferOwnershipExternal(ppOutParameter);  
569 // TransferOwnershipExternal will assign to ppOutParameter, inc external ref, and
570 //  call ClearAndMarkDontNeuter()
571 //-----------------------------------------------------------------------------
572 template<class T>
573 class RSInitHolder
574 {
575 public:
576     // Default ctor. Must call Assign() later.
577     RSInitHolder()
578     {
579     };
580     RSInitHolder(T * pObject)
581     {
582         Assign(pObject);
583     }
584
585     void Assign(T * pObject)
586     {
587         _ASSERTE(m_pObject == NULL); // only assign once.
588         m_pObject.Assign(pObject);
589     }
590     ~RSInitHolder();
591
592     FORCEINLINE operator T *() const
593     {
594         return m_pObject;
595     
596     }
597     FORCEINLINE T * operator->()
598     {
599         return m_pObject;
600     }
601
602     // This will null out m_pObject such that the dtor will not neuter it.
603     // This will also release the ref we took in the ctor.
604     // This will clear the current pointer.
605     void ClearAndMarkDontNeuter()
606     {
607         m_pObject.Clear();
608     }
609
610     //
611     // Transfer ownership to a pointer
612     //
613     // Arguments:
614     //     ppOutParam - pointer to get ownership. External Reference is incremented.
615     //                   this pointer should do an external release.
616     //
617     // Notes:
618     //    This calls ClearAndMarkDontNeuter(). This holder is Empty after this.
619     template <class TOther>
620     void TransferOwnershipExternal(TOther ** ppOutParam)
621     {
622         *ppOutParam = static_cast<TOther*> (m_pObject);
623         m_pObject->ExternalAddRef();
624
625         ClearAndMarkDontNeuter();
626     }
627     
628     
629     //
630     // Transfer the ownership of the wrapped object to the given hash table.    
631     //
632     // Arguments:
633     //    pHashTable - hash table to take ownership. 
634     //
635     // Returns:
636     //    the contianing object for convenience. Throws on error (particularly
637     //    if it fails adding to the hash).
638     //
639     // Notes:
640     //    This calls ClearAndMarkDontNeuter(). This holder is Empty after this.  
641     T* TransferOwnershipToHash(CordbSafeHashTable<T> * pHashtable)
642     {
643         T* pObject = m_pObject;
644         pHashtable->AddBaseOrThrow(m_pObject);
645         ClearAndMarkDontNeuter();
646         return pObject;
647     }
648
649     //
650     // Used to pass into a function that will assign to us.
651     //
652     // Returns:
653     //     Address of this holder. This is like the & operator. 
654     //     This is provided for consistency with other holders which 
655     //     override the &operator.
656     RSInitHolder<T> * GetAddr()
657     {
658         return this;
659     }
660
661
662 protected:
663     RSSmartPtr<T> m_pObject;
664 };
665
666
667
668 //-----------------------------------------------------------------------------
669 // Have the extra level of indirection is useful for catching Cordbg errors.
670 //-----------------------------------------------------------------------------
671 #ifdef _DEBUG
672     // On debug, we have an opportunity to catch failing hresults during reproes.
673     #define ErrWrapper(hr) ErrWrapperHelper(hr, __FILE__, __LINE__)
674
675     inline HRESULT ErrWrapperHelper(HRESULT hr, const char * szFile, int line)
676     {
677         if (FAILED(hr))
678         {
679             DWORD dwErr = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgBreakOnErr);
680             if (dwErr)
681             {
682                 CONSISTENCY_CHECK_MSGF(false, ("Dbg Error break, hr=0x%08x, '%s':%d", hr, szFile, line));
683             }
684         }
685         return hr;
686     }
687 #else
688     // On release, it's just an identity function
689     #define ErrWrapper(hr) (hr)
690 #endif
691
692 //-----------------------------------------------------------------------------
693 // Quick helpers for threading semantics
694 //-----------------------------------------------------------------------------
695
696 bool IsWin32EventThread(CordbProcess* p);
697 bool IsRCEventThread(Cordb* p);
698
699 /* ------------------------------------------------------------------------- *
700  * Typedefs
701  * ------------------------------------------------------------------------- */
702
703 typedef void* REMOTE_PTR;
704
705
706 //-----------------------------------------------------------------------------
707 // Wrapper class for locks. This is like Crst on the LS
708 //-----------------------------------------------------------------------------
709
710 class RSLock
711 {
712 public:
713     // Attrs, can be bitwise-or together.
714     enum ELockAttr
715     {
716         cLockUninit     = 0x00000000,
717         cLockReentrant  = 0x00000001,
718         cLockFlat       = 0x00000002,
719
720         // (unusual).  Not considered a debug API lock, for purposes of deciding whether
721         // to count this lock in m_cTotalDbgApiLocks, which is asserted to be 0 on entry
722         // to public APIs.  Example of such a lock: LL_SHIM_PROCESS_DISPOSE_LOCK
723         cLockNonDbgApi  = 0x00000004,
724     };
725
726     // To prevent deadlocks, we order all locks.
727     // A thread must acquire higher-numbered locks before lower numbered locks.
728     // These are used as indices into an array, so number them accordingly!
729     enum ERSLockLevel
730     {
731         // Size of the array..
732         LL_MAX = 6,
733
734         // The Stop-Go lock is used to make Stop + Continue be atomic operations.
735         // These methods will toggle the Process-lock b/c they go between multiple threads.
736         // This lock can never be taken on the Win32 ET.
737         LL_STOP_GO_LOCK = 5,
738
739         // The win32-event-thread behaves as if it held a lock at this level.
740         LL_WIN32_EVENT_THREAD = 4,
741
742         // This held for the duration of ShimProcess::Dispose(), and protects
743         // ShimProcess::m_fIsDisposed, so that other ShimProcess functions can
744         // safely execute serially with ShimProcess::Dispose().  This needs to be
745         // a high-level lock, since ShimProcess methods that take this lock also
746         // call into CorDb* objects which take many of the other locks.  In contrast,
747         // LL_SHIM_LOCK must remain low-level, as there exists at least one place where
748         // LL_SHIM_LOCK is taken while the CorDbProcess lock is also held (see
749         // CordbThread::GetActiveFunctions which takes the CorDbProcess lock while
750         // calling GetProcess()->GetShim()->LookupOrCreateShimStackWalk(this), which
751         // takes LL_SHIM_LOCK).
752         LL_SHIM_PROCESS_DISPOSE_LOCK = 3,
753
754         // The process lock is the primary lock for a CordbProcess object. It synchronizes
755         // between RCET, W32ET, and user threads.
756         LL_PROCESS_LOCK = 2,
757
758 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
759         LL_DBG_TRANSPORT_MANAGER_LOCK = 1,
760
761         LL_DBG_TRANSPORT_TARGET_LOCK = 0,
762
763         LL_DD_MARSHAL_LOCK = 0,
764 #endif // FEATURE_DBGIPC_TRANSPORT_DI
765
766         // These are all leaf locks (they don't take any other lock once they're held).
767         LL_PROCESS_LIST_LOCK = 0,
768
769         // Win32 send lock is shared by all processes accessing a single w32et.
770         LL_WIN32_SEND_LOCK = 0,
771
772         // Small lock around sending IPC events to support workarounds in func-eval abort.
773         // See code:CordbEval::Abort for details.
774         LL_FUNC_EVAL_ABORT_HACK_LOCK = 0,
775
776         // Leaf-level lock used in the shim.
777         LL_SHIM_LOCK = 0
778     };
779
780     // Initialize a lock w/ debugging info. szTag must be a string literal.
781     void Init(const char * szTag, int eAttr, ERSLockLevel level);
782     void Destroy();
783
784     void Lock();
785     void Unlock();
786
787 protected:
788     // Accessors for holders.
789     static void HolderEnter(RSLock * pLock)
790     {
791         pLock->Lock();
792     }
793     static void HolderLeave(RSLock * pLock)
794     {
795         pLock->Unlock();
796     }
797
798
799     CRITICAL_SECTION m_lock;
800
801 #ifdef _DEBUG
802 public:
803     RSLock();
804     ~RSLock();
805
806     const char * Name() { return m_szTag; }
807
808     // Returns true if this thread has the lock.
809     bool HasLock();
810
811     // Returns true if this is safe to take on this thread (ie, this thread
812     // doesn't already hold bigger locks).
813     // bool IsSafeToTake();
814
815     ERSLockLevel GetLevel() { return m_level; }
816
817     // If we're inited, we must have either  cLockReentrant or cLockFlat specified.
818     bool IsInit() { return m_eAttr != 0; }
819     bool IsReentrant() { return (m_eAttr & cLockReentrant) == cLockReentrant; }
820     bool IsDbgApiLock() { return ((m_eAttr & cLockNonDbgApi) == 0); }
821
822 protected:
823     ERSLockLevel m_level;
824     int m_eAttr;        // Bitwise combination of ELockAttr values
825     int m_count;
826     DWORD m_tidOwner;
827     const char * m_szTag;
828
829 #endif // #if debug
830
831 public:
832     typedef Holder<RSLock *, RSLock::HolderEnter, RSLock::HolderLeave> RSLockHolder;
833     typedef Holder<RSLock *, RSLock::HolderLeave, RSLock::HolderEnter> RSInverseLockHolder;
834
835 };
836
837 typedef RSLock::RSLockHolder RSLockHolder;
838 typedef RSLock::RSInverseLockHolder RSInverseLockHolder;
839
840 // In the RS, we should be using RSLocks instead of raw critical sections.
841 #define CRITICAL_SECTION USE_RSLOCK_INSTEAD_OF_CRITICAL_SECTION
842
843
844 /* ------------------------------------------------------------------------- *
845  * Helper macros. Use the ATT_* macros below instead of these.
846  * ------------------------------------------------------------------------- */
847
848 // This serves as glue for exceptions. Eventually, we shouldn't have unrecoverable
849 // error, and instead, errors should just propogate up.
850 #define SetUnrecoverableIfFailed(__p, __hr) \
851     if (FAILED(__hr)) \
852     { \
853        CORDBSetUnrecoverableError(__p, __hr, 0); \
854     } 
855
856 #define CORDBSetUnrecoverableError(__p, __hr, __code) \
857     ((__p)->UnrecoverableError((__hr), (__code), __FILE__, __LINE__))
858
859 #define _CORDBCheckProcessStateOK(__p) \
860     (!((__p)->m_unrecoverableError) && !((__p)->m_terminated) && !((__p)->m_detached))
861
862 #define _CORDBCheckProcessStateOKAndSync(__p, __c) \
863     (!((__p)->m_unrecoverableError) && !((__p)->m_terminated) && !((__p)->m_detached) && \
864     (__p)->GetSynchronized())
865
866 // Worker to get failure HR from given state. If not in a failure state, it yields __defaultHR.
867 // If a caller knows that we're in a failure state, it can pass in a failure value for __defaultHR.
868 #define CORDBHRFromProcessStateWorker(__p, __c, __defaultHR) \
869         ((__p)->m_unrecoverableError ? CORDBG_E_UNRECOVERABLE_ERROR : \
870          ((__p)->m_detached ? CORDBG_E_PROCESS_DETACHED : \
871          ((__p)->m_terminated ? CORDBG_E_PROCESS_TERMINATED : \
872          (!(__p)->GetSynchronized() ? CORDBG_E_PROCESS_NOT_SYNCHRONIZED \
873          : (__defaultHR)))))
874
875 #define CORDBHRFromProcessState(__p, __c) \
876     CORDBHRFromProcessStateWorker(__p, __c, S_OK) \
877
878
879 // Have a set of helper macros to check the process state and return a failure code.
880 // These only should be used at public interface boundaries, in which case we should
881 // not be holding the process lock. But we have enough places where we use them internally,
882 // so we can't really assert that we're not holding the lock.
883
884 // We're very restricted in what APIs we can call on the w32et. Have
885 // a convenient check for this.
886 // If we have no shim, then nop this check because everything becomes like the w32-event-thread.
887 #define CORDBFailOrThrowIfOnWin32EventThread(__p, errorAction) \
888     { \
889         if (((__p)->GetShim() != NULL) && (__p)->IsWin32EventThread()) \
890         { \
891             _ASSERTE(!"Don't call on this thread"); \
892             errorAction(ErrWrapper(CORDBG_E_CANT_CALL_ON_THIS_THREAD)); \
893         } \
894     }
895
896 #define CORDBFailIfOnWin32EventThread(__p) CORDBFailOrThrowIfOnWin32EventThread(__p, return)
897
898 #define CORDBRequireProcessStateOK(__p) { \
899     if (!_CORDBCheckProcessStateOK(__p)) \
900         return ErrWrapper(CORDBHRFromProcessState(__p, NULL)); }
901
902 // If we need to be synced, then we shouldn't be on the win32 Event-Thread.
903 #define CORDBRequireProcessStateOKAndSync(__p,__c) { \
904     CORDBFailIfOnWin32EventThread(__p); \
905     if (!_CORDBCheckProcessStateOKAndSync(__p, __c)) \
906         return ErrWrapper(CORDBHRFromProcessState(__p, __c)); }
907
908 #define CORDBRequireProcessSynchronized(__p, __c) { \
909     CORDBFailIfOnWin32EventThread(__p); \
910     if (!(__p)->GetSynchronized()) return ErrWrapper(CORDBG_E_PROCESS_NOT_SYNCHRONIZED);}
911
912
913        
914
915 //-----------------------------------------------------------------------------
916 // All public APIS fall into 2 categories regarding their API Threading Type (ATT)
917 // We use a standard set of macros to define & enforce each type.
918 //
919 // (1) ATT_REQUIRE_STOPPED
920 // We must be stopped (either synced or at a win32 event) to call this API.
921 // - We'll fail if we're not stopped.
922 // - If we're stopped, we'll sync. Thus after this API, we're always synced,
923 //   and Cordbg must call Continue to resume the process.
924 // - We'll take the Stop-Go-lock. This prevents another thread from continuing underneath us.
925 // - We may send IPC events.
926 // Common for APIs like Stacktracing
927 //
928 // (2) ATT_ALLOW_LIVE
929 // We do not have to be stopped to call this API.
930 // - We can be live, thus we can not take the stop-go lock (unless it's from a SC-holder).
931 // - If we're going to send IPC events, we must use a Stop-Continue holder.
932 // - Our stop-status is the same after this API as it was before.
933 // Common usage: read-only APIs.
934 //
935 // (2b) ATT_ALLOW_LIVE_DO_STOPGO.
936 // - shortcut macro to do #2, but throw in a stop-continue holder. These really
937 // should be in camp #1, but that would require an interface change.
938 //-----------------------------------------------------------------------------
939
940 // Helper macros for the ATT stuff
941
942 // Do checks that need to be done before we take the SG lock. These include checks
943 // where if we fail them, taking the SG lock could deadlock (such as being on win32 thread).
944 #define DO_PRE_STOP_GO_CHECKS(errorAction) \
945     CORDBFailOrThrowIfOnWin32EventThread(__proc_for_ATT, errorAction) \
946     if ((__proc_for_ATT)->m_unrecoverableError) { errorAction(CORDBG_E_UNRECOVERABLE_ERROR); } \
947
948 // Do checks after we take the SG lock. These include checks that rely on state protected
949 // by the SG lock.
950 #define DO_POST_STOP_GO_CHECKS(errorAction) \
951     _ASSERTE((this->GetProcess() == __proc_for_ATT) || this->IsNeutered()); \
952     if (this->IsNeutered()) { errorAction(CORDBG_E_OBJECT_NEUTERED); } \
953
954 // #1
955 // The exact details here are rocket-science.
956 // We cache the __proc value to a local variable (__proc_for_ATT) so that we don't re-evaluate __proc. (It also forces type-safety).
957 // This is essential in case __proc is something like "this->GetProcess()" and which can start returning NULL if 'this' 
958 // gets neutered underneath us. Caching guarantees that we'll be able to make it to the StopGo-lock. 
959 // 
960 // We explicitily check some things before taking the Stop-Go lock:
961 // - CORDBG_E_UNRECOVERABLE_ERROR before the lock because if that's set,
962 //   we may have leaked locks to the outside world, so taking the StopGo lock later could fail.
963 // - Are we on the W32et - can't take sg lock if on W32et
964 // Then we immediately take the stop-go lock to prevent another thread from continuing underneath us.
965 // Then, if we're stopped, we ensure that we're also synced.
966 // Stopped includes:
967 // - Win32-stopped
968 // - fake win32-stopped. Eg, between SuspendUnmanagedThreads & ResumeUnmanagedThreads
969 //   (one way to get here is getting debug events during the special-deferment region)
970 // - synchronized
971 // If we're not stopped, then we fail.  This macro must never return S_OK.
972 //
973 // If not-shimmed (using V3 pipeline), then skip all checks about stop-state.
974 #define ATT_REQUIRE_STOPPED_MAY_FAIL_OR_THROW(__proc, errorAction) \
975     CordbProcess * __proc_for_ATT = (__proc); \
976     DO_PRE_STOP_GO_CHECKS(errorAction); \
977     RSLockHolder __ch(__proc_for_ATT->GetStopGoLock()); \
978     DO_POST_STOP_GO_CHECKS(errorAction); \
979     if ((__proc_for_ATT)->GetShim() != NULL) { \
980         if (!__proc_for_ATT->m_initialized) { errorAction(CORDBG_E_NOTREADY); } \
981         if ((__proc_for_ATT)->IsStopped()) { \
982             HRESULT _hr2 = (__proc_for_ATT)->StartSyncFromWin32Stop(NULL); \
983             if (FAILED(_hr2)) errorAction(_hr2); \
984         } \
985         if (!_CORDBCheckProcessStateOKAndSync(__proc_for_ATT, NULL)) \
986             errorAction(CORDBHRFromProcessStateWorker(__proc_for_ATT, NULL, E_FAIL)); \
987     }
988
989 #define ATT_REQUIRE_STOPPED_MAY_FAIL(__proc)ATT_REQUIRE_STOPPED_MAY_FAIL_OR_THROW(__proc, return) 
990
991 // #1b - allows it to be non-inited. This should look just like ATT_REQUIRE_STOPPED_MAY_FAIL_OR_THROW
992 // except it doesn't do SSFW32Stop and doesn't have the m_initialized check.
993 #define ATT_REQUIRE_SYNCED_OR_NONINIT_MAY_FAIL(__proc) \
994     CordbProcess * __proc_for_ATT = (__proc); \
995     DO_PRE_STOP_GO_CHECKS(return); \
996     RSLockHolder __ch(__proc_for_ATT->GetStopGoLock()); \
997     DO_POST_STOP_GO_CHECKS(return); \
998     if ((__proc_for_ATT)->GetShim() != NULL) { \
999         if (!_CORDBCheckProcessStateOKAndSync(__proc_for_ATT, NULL)) \
1000             return CORDBHRFromProcessStateWorker(__proc_for_ATT, NULL, E_FAIL); \
1001     }
1002
1003
1004
1005 // Gross variant on #1.
1006 // This is a very dangerous ATT contract; but we need to support it for backwards compat.
1007 // Some APIs, like ICDProcess:EnumerateThreads can be used before the process is actually
1008 // initialized (kind of for interop-debugging).
1009 // These can't check the m_initialized flag b/c that may not be set yet.
1010 // They also can't sync the runtime.
1011 // This should only be used for non-blocking leaf activity.
1012 #define ATT_EVERETT_HACK_REQUIRE_STOPPED_ALLOW_NONINIT(__proc) \
1013     CordbProcess * __proc_for_ATT = (__proc); \
1014     DO_PRE_STOP_GO_CHECKS(return); \
1015     RSLockHolder __ch(__proc_for_ATT->GetStopGoLock()); \
1016     DO_POST_STOP_GO_CHECKS(return); \
1017     if (((__proc_for_ATT)->GetShim() != NULL) && !(__proc_for_ATT)->IsStopped()) { return CORDBG_E_PROCESS_NOT_SYNCHRONIZED; } \
1018
1019
1020 // #2 - caller may think debuggee is live, but throw in a Stop-Continue holder.
1021 #define ATT_ALLOW_LIVE_DO_STOPGO(__proc) \
1022     CordbProcess * __proc_for_ATT = (__proc); \
1023     DO_PRE_STOP_GO_CHECKS(return); \
1024     CORDBRequireProcessStateOK(__proc_for_ATT); \
1025     RSLockHolder __ch(__proc_for_ATT->GetStopGoLock()); \
1026     DO_POST_STOP_GO_CHECKS(return); \
1027     StopContinueHolder __hStopGo; \
1028     if ((__proc_for_ATT)->GetShim() != NULL) \
1029     { \
1030         HRESULT _hr2 = __hStopGo.Init(__proc_for_ATT); \
1031         if (FAILED(_hr2)) return _hr2; \
1032         _ASSERTE((__proc_for_ATT)->GetSynchronized()); \
1033     } \
1034
1035
1036
1037
1038 //-----------------------------------------------------------------------------
1039 // StopContinueHolder. Ensure that we're synced during a certain region.
1040 // (Particularly when sending an IPCEvent)
1041 // Calls ICorDebugProcess::Stop & IMDArocess::Continue.
1042 // Example usage:
1043 //
1044 // {
1045 //   StopContinueHolder h;
1046 //   IfFailRet(h.Init(process))
1047 //   SendIPCEvent
1048 // } // continue automatically called.
1049 //-----------------------------------------------------------------------------
1050
1051 class CordbProcess;
1052 class StopContinueHolder
1053 {
1054 public:
1055     StopContinueHolder() : m_p(NULL) { };
1056
1057     HRESULT Init(CordbProcess * p);
1058     ~StopContinueHolder();
1059
1060 protected:
1061     CordbProcess * m_p;
1062 };
1063
1064
1065 /* ------------------------------------------------------------------------- *
1066  * Base class
1067  * ------------------------------------------------------------------------- */
1068
1069 #define COM_METHOD  HRESULT STDMETHODCALLTYPE
1070
1071 typedef enum {
1072     enumCordbUnknown,       //  0
1073     enumCordb,              //  1   1  [1]x1
1074     enumCordbProcess,       //  2   1  [1]x1
1075     enumCordbAppDomain,     //  3   1  [1]x1
1076     enumCordbAssembly,      //  4
1077     enumCordbModule,        //  5   15 [27-38,55-57]x1
1078     enumCordbClass,         //  6
1079     enumCordbFunction,      //  7
1080     enumCordbThread,        //  8   2  [4,7]x1
1081     enumCordbCode,          //  9
1082     enumCordbChain,         //  10
1083     enumCordbChainEnum,     //  11
1084     enumCordbContext,       //  12
1085     enumCordbFrame,         //  13
1086     enumCordbFrameEnum,     //  14
1087     enumCordbValueEnum,     //  15
1088     enumCordbRegisterSet,   //  16
1089     enumCordbJITILFrame,    //  17
1090     enumCordbBreakpoint,    //  18
1091     enumCordbStepper,       //  19
1092     enumCordbValue,         //  20
1093     enumCordbEnCSnapshot,   //  21
1094     enumCordbEval,          //  22
1095     enumCordbUnmanagedThread,// 23
1096     enumCorpubPublish,      //  24
1097     enumCorpubProcess,      //  25
1098     enumCorpubAppDomain,    //  26
1099     enumCorpubProcessEnum,  //  27
1100     enumCorpubAppDomainEnum,//  28
1101     enumCordbEnumFilter,    //  29
1102     enumCordbEnCErrorInfo,  //  30
1103     enumCordbEnCErrorInfoEnum,//31
1104     enumCordbUnmanagedEvent,//  32
1105     enumCordbWin32EventThread,//33
1106     enumCordbRCEventThread, //  34
1107     enumCordbNativeFrame,   //  35
1108     enumCordbObjectValue,   //  36
1109     enumCordbType,          //  37
1110     enumCordbNativeCode,    //  38
1111     enumCordbILCode,        //  39
1112     enumCordbEval2,         //  40
1113     enumCordbMDA,           //  41
1114     enumCordbHashTableEnum, //  42
1115     enumCordbCodeEnum,      //  43
1116     enumCordbStackWalk,     //  44
1117     enumCordbEnumerator,    //  45
1118     enumCordbHeap,          //  48
1119     enumCordbHeapSegments,  //  47
1120     enumMaxDerived,         //
1121     enumMaxThis = 1024
1122 } enumCordbDerived;
1123
1124
1125
1126 //-----------------------------------------------------------------------------
1127 // Support for Native Breakpoints
1128 //-----------------------------------------------------------------------------
1129 struct NativePatch
1130 {
1131     void * pAddress; // pointer into the LS address space.
1132     PRD_TYPE opcode; // opcode to restore with.
1133
1134     inline bool operator==(NativePatch p2)
1135     {
1136         return memcmp(this, &p2, sizeof(p2)) == 0;
1137     }
1138 };
1139
1140 //-----------------------------------------------------------------------------
1141 // Cross-platform patch operations
1142 //-----------------------------------------------------------------------------
1143
1144 // Remove the int3 from the remote address
1145 HRESULT RemoveRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE opcode);
1146
1147 // This flavor is assuming our caller already knows the opcode.
1148 HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress);
1149
1150 // Apply the patch and get the opcode that we're replacing.
1151 HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE * pOpcode);
1152
1153
1154 class CordbHashTable;
1155
1156 #define CORDB_COMMON_BASE_SIGNATURE 0x0d00d96a
1157 #define CORDB_COMMON_BASE_SIGNATURE_DEAD 0x0dead0b1
1158
1159 // Common base for both CorPublish + CorDebug objects.
1160 class CordbCommonBase : public IUnknown
1161 {
1162 public:
1163     // GENERIC: made this private as I'm changing the use of m_id for CordbClass, and
1164     // I want to make sure I catch all the places where m_id is used directly and cast
1165     // to/from tokens and/or (void*).
1166     UINT_PTR    m_id;
1167
1168 #ifdef _DEBUG
1169     static LONG m_saDwInstance[enumMaxDerived]; // instance x this
1170     static LONG m_saDwAlive[enumMaxDerived];
1171     static PVOID m_sdThis[enumMaxDerived][enumMaxThis];
1172     DWORD m_dwInstance;
1173     enumCordbDerived m_type;
1174 #endif
1175
1176
1177
1178 private:
1179     DWORD       m_signature : 30;
1180
1181     // Sticky bit set when we neuter an object. All methods (besides AddRef,Release,QI)
1182     // should check this bit and fail via the FAIL_IF_NEUTERED macro.
1183     DWORD        m_fIsNeutered : 1;
1184
1185     // Mark that this object can be "neutered at will". NeuterList::SweepAllNeuterAtWillObjects
1186     // looks at this bit.
1187     // For some objects, we don't explicitly mark when the lifetime is up. The only way
1188     // we know is when external count goes to 0. This avoids forcing us to do cleanup
1189     // in the dtor (which may come at a bad time). Sticky bit set in BaseRelease().
1190     DWORD        m_fNeuterAtWill : 1;
1191 public:
1192
1193     static LONG s_CordbObjectUID;    // Unique ID for each object.
1194     static LONG s_TotalObjectCount; // total number of outstanding objects.
1195
1196
1197     void ValidateObject()
1198     {
1199         if( !IsValidObject() )
1200         {
1201             STRESS_LOG1(LF_ASSERT, LL_ALWAYS, "CordbCommonBase::IsValidObject() failed: %x\n", this);
1202             _ASSERTE(!"CordbCommonBase::IsValidObject() failed");
1203             FreeBuildDebugBreak();
1204         }
1205     }
1206
1207     bool IsValidObject()
1208     {
1209         return (m_signature == CORDB_COMMON_BASE_SIGNATURE);
1210     }
1211
1212     CordbCommonBase(UINT_PTR id, enumCordbDerived type)
1213     {
1214         init(id, type);
1215     }
1216
1217     CordbCommonBase(UINT_PTR id)
1218     {
1219         init(id, enumCordbUnknown);
1220     }
1221
1222     void init(UINT_PTR id, enumCordbDerived type)
1223     {
1224         // To help us track object leaks, we want to log when we create & destory CordbBase objects.
1225 #ifdef _DEBUG
1226         InterlockedIncrement(&s_TotalObjectCount);
1227         InterlockedIncrement(&s_CordbObjectUID);
1228
1229         LOG((LF_CORDB, LL_EVERYTHING, "Memory: CordbBase object allocated: this=%p, count=%d, id=%p, Type=%d\n", this, s_CordbObjectUID, id, type));
1230 #endif
1231
1232         m_signature = CORDB_COMMON_BASE_SIGNATURE;
1233         m_fNeuterAtWill = 0;
1234         m_fIsNeutered = 0;
1235
1236         m_id = id;
1237         m_RefCount = 0;
1238
1239 #ifdef _DEBUG
1240         m_type = type;
1241         //m_dwInstance = CordbBase::m_saDwInstance[m_type];
1242         //InterlockedIncrement(&CordbBase::m_saDwInstance[m_type]);
1243         //InterlockedIncrement(&CordbBase::m_saDwAlive[m_type]);
1244         //if (m_dwInstance < enumMaxThis)
1245         //{
1246         //    m_sdThis[m_type][m_dwInstance] = this;
1247         //}
1248 #endif
1249     }
1250
1251     virtual ~CordbCommonBase()
1252     {
1253         // If we're deleting, we really should have released any outstanding reference.
1254         // If we call Release() on a deleted object, we'll av (especially b/c Release
1255         // may call delete again).
1256         CONSISTENCY_CHECK_MSGF(m_RefCount == 0, ("Deleting w/ non-zero ref count. 0x%08x", m_RefCount));
1257
1258 #ifdef _DEBUG
1259         //InterlockedDecrement(&CordbBase::m_saDwAlive[m_type]);
1260         //if (m_dwInstance < enumMaxThis)
1261         //{
1262         //    m_sdThis[m_type][m_dwInstance] = NULL;
1263         //}
1264 #endif
1265         // To help us track object leaks, we want to log when we create & destory CordbBase objects.
1266         LOG((LF_CORDB, LL_EVERYTHING, "Memory: CordbBase object deleted: this=%p, id=%p, Refcount=0x%x\n", this, m_id, m_RefCount));
1267
1268 #ifdef _DEBUG
1269         LONG newTotalObjectsCount = InterlockedDecrement(&s_TotalObjectCount);
1270         _ASSERTE(newTotalObjectsCount >= 0);
1271 #endif
1272
1273         // Don't shutdown logic until everybody is done with it.
1274         // If we leak objects, this may mean that we never shutdown logging at all!
1275 #if defined(_DEBUG) && defined(LOGGING)
1276         if (newTotalObjectsCount == 0)
1277         {
1278             ShutdownLogging();
1279         }
1280 #endif
1281     }
1282
1283     /*
1284         Member function behavior of a neutered COM object:
1285
1286              1. AddRef(), Release(), QueryInterface() work as normal.
1287                  a. This gives folks who are responsible for pairing a Release() with
1288                     an AddRef() a chance to dereference their pointer and call Release()
1289                     when they are informed, explicitly or implicitly, that the object is neutered.
1290
1291              2. Any other member function will return an error code unless documented.
1292                  a. If a member function returns information when the COM object is
1293                     neutered then the semantics of that function need to be documented.
1294                     (ie. If an AppDomain is unloaded and you have a reference to the COM
1295                     object representing the AppDomain, how _should_ it behave? That behavior
1296                     should be documented)
1297
1298
1299         Postcondions of Neuter():
1300
1301              1. All circular references (aka back-pointers) are "broken". They are broken
1302                 by calling Release() on all "Weak References" to the object. If you're a purist,
1303                 these pointers should also be NULLed out.
1304                  a. Weak References/Strong References:
1305                      i. If any objects are not "reachable" from the root (ie. stack or from global pointers)
1306                          they should be reclaimed. If they are not, they are leaked and there is an issue.
1307                      ii. There must be a partial order on the objects such that if A < B then:
1308                          1. A has a reference to B. This reference is a "strong reference"
1309                          2. A, and thus B, is reachable from the root
1310                      iii. If a reference belongs in the partial order then it is a "strong reference" else
1311                          it is a weak reference.
1312          *** 2. Sufficient conditions to ensure no COM objects are leaked: ***
1313                 a. When Neuter() is invoked:
1314                      i. Calles Release on all its weak references.
1315                      ii. Then, for each strong reference:
1316                          1. invoke Neuter()
1317                          2. invoke Release()
1318                      iii. If it's derived from a CordbXXX class, call Neuter() on the base class.
1319                          1. Sense Neuter() is virtual, use the scope specifier Cordb[BaseClass]::Neuter().
1320              3. All members return error codes, except:
1321                  a. Members of IUknown, AddRef(), Release(), QueryInterfac()
1322                  b. Those documented to have functionality when the object is neutered.
1323                      i. Neuter() still works w/o error. If it is invoke a second time it will have already
1324                         released all its strong and weak references so it could just return.
1325
1326
1327         Alternate design ideas:
1328
1329              DESIGN: Note that it's possible for object B to have two parents in the partial order
1330                      and it must be documented which one is responsible for calling Neuter() on B.
1331                       1. For example, CordbCode could reasonably be a sibling of CordbFunction and CordbNativeFrame.
1332                          Which one should call Release()? For now we have CordbFunction call Release() on CordbCode.
1333
1334              DESIGN: It is not a necessary condition in that Neuter() invoke Release() on all
1335                      it's strong references. Instead, it would be sufficient to ensure all object are released, that
1336                      each object call Release() on all its strong pointers in its destructor.
1337                       1. This might be done if its necessary for some member to return "tombstone"
1338                          information after the object has been netuered() which involves the siblings (wrt poset)
1339                          of the object. However, no sibling could access a parent (wrt poset) because
1340                          Neuter called Release() on all its weak pointers.
1341
1342              DESIGN: Rename Neuter() to some name that more accurately reflect the semantics.
1343                      1. The three operations are:
1344                          a. ReleaseWeakPointers()
1345                          b. NeuterStrongPointers()
1346                          c. ReleaseStrongPointers()
1347                              1. Assert that it's done after NeuterStrongPointers()
1348                      2. That would introduce a bunch of functions... but it would be clear.
1349
1350              DESIGN: CordbBase could provide a function to register strong and weak references. That way CordbBase
1351                      could implement a general version of ReleaseWeak/ReleaseStrong/NeuterStrongPointers(). This
1352                      would provide a very error resistant framework for extending the object model plus it would
1353                      be very explicit about what is going on.
1354                          One thing that might trip this is idea up is that if an object has two parents,
1355                          like the CordbCode might, then either both objects call Neuter or one is reference
1356                          is made weak.
1357
1358
1359         Our implementation:
1360
1361            The graph formed by the strong references must remain acyclic.
1362            It's up to the developer (YOU!) to ensure that each Neuter
1363            function maintains that invariant.
1364
1365            Here is the current Partial Order on CordbXXX objects. (All these classes
1366            eventually chain to CordbBase.Neuter() for completeness.)
1367
1368            Cordb
1369               CordbProcess
1370                   CordbAppDomain
1371                       CordbBreakPoints
1372                       CordbAssembly
1373                       CordbModule
1374                           CordbClass
1375                           CordbFunction
1376                               CordbCode (Can we assert a thread will not reference
1377                                           the same CordbCode as a CordbFunction?)
1378                  CordbThread
1379                      CordbChains
1380                      CordbNativeFrame -> CordbFrame (Chain to baseClass)
1381                          CordbJITILFrame
1382
1383
1384             <TODO>TODO: Some Neuter functions have not yet been implemented due to time restrictions.</TODO>
1385
1386             <TODO>TODO: Some weak references never have AddRef() called on them. If that's cool then
1387                   it should be stated in the documentation. Else it should be changed.</TODO>
1388 */
1389
1390     virtual void Neuter();
1391
1392     // Unsafe neuter for an object that's already dead.
1393     void UnsafeNeuterDeadObject();
1394
1395
1396 #ifdef _DEBUG
1397     // For debugging (asserts, logging, etc) provide a pretty name (this is 1:1 w/ the VTable)
1398     // We provide a default impl in the base object in case this gets called from a dtor (virtuals
1399     // called from dtors use the base version, not the derived). A pure call would AV in that case.
1400     virtual const char * DbgGetName() { return "CordbBase"; };
1401 #endif
1402
1403     bool IsNeutered() const {LIMITED_METHOD_CONTRACT;  return m_fIsNeutered == 1; }
1404     bool IsNeuterAtWill() const { LIMITED_METHOD_CONTRACT; return m_fNeuterAtWill == 1; }
1405     void MarkNeuterAtWill() { LIMITED_METHOD_CONTRACT; m_fNeuterAtWill = 1; }
1406
1407     //-----------------------------------------------------------
1408     // IUnknown support
1409     //----------------------------------------------------------
1410
1411 private:
1412     // We maintain both an internal + external refcount. This allows us to catch
1413     // if an external caller has too many releases.
1414     // low  bits are internal count, high  bits are external count
1415     // so Total count = (m_RefCount & CordbBase_InternalRefCountMask) + (m_RefCount >> CordbBase_ExternalRefCountShift);
1416     typedef LONGLONG       MixedRefCountSigned;
1417     typedef ULONGLONG      MixedRefCountUnsigned;
1418     typedef LONG           ExternalRefCount;
1419     MixedRefCountUnsigned  m_RefCount;
1420 public:
1421
1422     // Adjust the internal ref count.
1423     // These aren't available to the external world, so only internal code can manipulate the internal count.
1424     void InternalAddRef();
1425     void InternalRelease();
1426
1427     // Derived versions of AddRef / Release will call these.
1428     // External AddRef & Release
1429     // These do not have any additional Asserts to enforce that we're not manipulating the external count
1430     // from internal.
1431     ULONG STDMETHODCALLTYPE BaseAddRef();
1432     ULONG STDMETHODCALLTYPE BaseRelease();
1433
1434     // External ref count versions, with extra debug count to enforce that this is done externally.
1435     // When derive classes use these versions, it Asserts that we're not adjusting external counts from inside.
1436     // Thus we can be confident that we're *never* leaking external refs to these objects.
1437     // @todo - eventually everything should use these.
1438     ULONG STDMETHODCALLTYPE BaseAddRefEnforceExternal();
1439     ULONG STDMETHODCALLTYPE BaseReleaseEnforceExternal();
1440
1441     // Do an AddRef against the External count. This is a semantics issue.
1442     // We use this when an internal component Addrefs out-parameters (which Cordbg will call Release on).
1443     // This just does a regular external AddRef().
1444     void ExternalAddRef();
1445
1446 protected:
1447
1448     static void InitializeCommon();
1449
1450 private:
1451     static void AddDebugPrivilege();
1452 };
1453
1454 #define CordbBase_ExternalRefCountShift 32
1455 #define CordbBase_InternalRefCountMask 0xFFFFFFFF
1456 #define CordbBase_InternalRefCountMax  0x7FFFFFFF
1457
1458 #ifdef _DEBUG
1459 // Does the given Cordb object type have affinity to a CordbProcess object?
1460 // This is only used for certain asserts.
1461 inline bool DoesCordbObjectTypeHaveProcessPtr(enumCordbDerived type)
1462 {
1463     return 
1464         (type != enumCordbCodeEnum) &&
1465         (type != enumCordb) &&
1466         (type != enumCordbHashTableEnum);
1467 }
1468 #endif
1469
1470 // Base class specifically for CorDebug objects
1471 class CordbBase : public CordbCommonBase
1472 {
1473 public:
1474     CordbBase(CordbProcess * pProcess, UINT_PTR id, enumCordbDerived type) : CordbCommonBase(id, type)
1475     {
1476         // CordbProcess can't pass 'this' to base class, per error C4355. So we pass null and set later.
1477         _ASSERTE((pProcess != NULL) || 
1478             ((type) == enumCordbProcess) ||
1479             !DoesCordbObjectTypeHaveProcessPtr(type));
1480
1481         m_pProcess.Assign(pProcess);
1482     }
1483
1484     CordbBase(CordbProcess * pProcess, UINT_PTR id) : CordbCommonBase(id)
1485     {
1486         _ASSERTE(pProcess != NULL);
1487         m_pProcess.Assign(pProcess);
1488     }
1489
1490     virtual ~CordbBase()
1491     {
1492         // Derived classes should not have cleared out our pointer.
1493         // CordbProcess's Neuter explicitly nulls out its pointer to avoid circular reference.
1494         _ASSERTE(m_pProcess!= NULL || 
1495             (CordbCommonBase::m_type == enumCordbProcess) ||
1496             !DoesCordbObjectTypeHaveProcessPtr(CordbCommonBase::m_type));
1497         
1498         // Ideally, all CorDebug objects to be neutered by the time their dtor is called.
1499         // @todo - we're still working out neutering semantics for a few remaining objects, so we exclude
1500         // those from the assert.
1501         _ASSERTE(IsNeutered() ||
1502             (m_type == enumCordbBreakpoint) ||
1503             (m_type == enumCordbStepper));
1504     }
1505
1506     // Neuter just the right-side state.
1507     virtual void Neuter();
1508
1509     // Neuter both left-side state and right-side state.
1510     virtual void NeuterLeftSideResources();
1511
1512     // Get the CordbProcess object that this CordbBase object is associated with (or NULL if there's none).
1513     CordbProcess * GetProcess() const
1514     {
1515         return m_pProcess;
1516     }
1517 protected:
1518     // All objects need a strong pointer back to the process so that they can get access to key locks
1519     // held by the process (StopGo lock) so that they can synchronize their operations against neutering.
1520     // This pointer is cleared in our dtor, and not when we're neutered. Since we can't control when the
1521     // dtor is called (it's controlled by external references), we classify this as an external reference too.
1522     //
1523     // This is the only "strong" reference backpointer that objects need have. All other backpointers can be weak references
1524     // because when a parent object is neutered, it will null out all weak reference pointers in all of its children.
1525     // That will also break any potential cycles.     
1526     RSUnsafeExternalSmartPtr<CordbProcess> m_pProcess;
1527
1528 };
1529
1530
1531
1532
1533
1534 //-----------------------------------------------------------------------------
1535 // Macro to check if a CordbXXX object is neutered, and return a standard
1536 // error code if it is.
1537 // We pass the 'this' pointer of the object in because it gives us some extra
1538 // flexibility and lets us log debug info.
1539 // It is an API breach to access a neutered object.
1540 //-----------------------------------------------------------------------------
1541 #define FAIL_IF_NEUTERED(pThis) \
1542 int _____Neuter_Status_Already_Marked; \
1543 _____Neuter_Status_Already_Marked = 0; \
1544 {\
1545     if (pThis->IsNeutered()) { \
1546             LOG((LF_CORDB, LL_ALWAYS, "Accessing a neutered object at %p\n", pThis)); \
1547             return ErrWrapper(CORDBG_E_OBJECT_NEUTERED); \
1548     } \
1549 }
1550
1551 //-----------------------------------------------------------------------------
1552 // Macro to check if a CordbXXX object is neutered, and return a standard
1553 // error code if it is.
1554 // We pass the 'this' pointer of the object in because it gives us some extra
1555 // flexibility and lets us log debug info.
1556 // It is an API breach to access a neutered object.
1557 //-----------------------------------------------------------------------------
1558 #define THROW_IF_NEUTERED(pThis) \
1559 int _____Neuter_Status_Already_Marked; \
1560 _____Neuter_Status_Already_Marked = 0; \
1561 {\
1562     if (pThis->IsNeutered()) { \
1563             LOG((LF_CORDB, LL_ALWAYS, "Accessing a neutered object at %p\n", pThis)); \
1564             ThrowHR(CORDBG_E_OBJECT_NEUTERED); \
1565     } \
1566 }
1567
1568 // We have an OK_IF_NEUTERED macro to say that this method can be safely
1569 // called if we're neutered. Mostly for semantic benefits.
1570 // Also, if a method is marked OK, then somebody won't go and add a 'fail'
1571 // This is an extremely dangerous quality because:
1572 // 1) it means that we have no synchronization (can't take the Stop-Go lock)
1573 // 2) none of our backpointers are usable (they may be nulled out at anytime by another thread).
1574 //    - this also means we absolutely can't send IPC events (since that requires a CordbProcess)
1575 // 3) The only safe data are blittalbe embedded fields (eg, a pid or stack range) 
1576 //
1577 // Any usage of this macro should clearly specify why this is safe.
1578 #define OK_IF_NEUTERED(pThis) \
1579 int _____Neuter_Status_Already_Marked; \
1580 _____Neuter_Status_Already_Marked = 0;
1581
1582
1583 //-------------------------------------------------------------------------------
1584 // Simple COM enumerator pattern on a fixed list of items
1585 //--------------------------------------------------------------------------------
1586 template< typename ElemType,
1587           typename ElemPublicType,
1588           typename EnumInterfaceType,
1589           ElemPublicType (*GetPublicType)(ElemType)>
1590 class CordbEnumerator : public CordbBase, public EnumInterfaceType
1591 {
1592 private:
1593     // the list of items being enumerated over
1594     ElemType *m_items;
1595     // the number of items in the list
1596     DWORD m_countItems;
1597     // the index of the next item to be returned in the enumeration
1598     DWORD m_nextIndex;
1599
1600 public:
1601     // makes a copy of the elements in the "items" array
1602     CordbEnumerator(CordbProcess* pProcess, ElemType *items, DWORD elemCount);
1603     // assumes ownership of the elements in the "*items" array.
1604     // this avoids an extra allocation + copy
1605     CordbEnumerator(CordbProcess* pProcess, ElemType **items, DWORD elemCount);
1606     ~CordbEnumerator();
1607
1608 // IUnknown interface
1609     virtual COM_METHOD QueryInterface(REFIID riid, VOID** ppInterface);
1610     virtual ULONG __stdcall AddRef();
1611     virtual ULONG __stdcall Release();
1612
1613 // ICorDebugEnum interface
1614     virtual COM_METHOD Clone(ICorDebugEnum **ppEnum);
1615     virtual COM_METHOD GetCount(ULONG *pcelt);
1616     virtual COM_METHOD Reset();
1617     virtual COM_METHOD Skip(ULONG celt);
1618
1619 // ICorDebugXXXEnum interface
1620     virtual COM_METHOD Next(ULONG celt, ElemPublicType items[], ULONG *pceltFetched);
1621
1622 // CordbBase overrides
1623     virtual VOID Neuter();
1624 };
1625
1626 // Converts T to U* by using QueryInterface
1627 template<typename T, typename U>
1628 U* QueryInterfaceConvert(T obj);
1629
1630 // No conversion, just returns the argument
1631 template<typename T>
1632 T IdentityConvert(T obj);
1633
1634 // CorDebugGuidToTypeMapping-adapter used by CordbGuidToTypeEnumerator 
1635 // in the CordbEnumerator pattern
1636 struct RsGuidToTypeMapping
1637 {
1638     GUID iid;
1639     RSSmartPtr<CordbType> spType;
1640 };
1641
1642 inline
1643 CorDebugGuidToTypeMapping GuidToTypeMappingConvert(RsGuidToTypeMapping m)
1644 {
1645     CorDebugGuidToTypeMapping result;
1646     result.iid = m.iid;
1647     result.pType = (ICorDebugType*)(m.spType.GetValue());
1648     result.pType->AddRef();
1649     return result;
1650 }
1651
1652 //
1653 // Some useful enumerators
1654 //
1655 typedef CordbEnumerator<RSSmartPtr<CordbThread>,
1656                         ICorDebugThread*,
1657                         ICorDebugThreadEnum,
1658                         QueryInterfaceConvert<RSSmartPtr<CordbThread>, ICorDebugThread> > CordbThreadEnumerator;
1659
1660 typedef CordbEnumerator<CorDebugBlockingObject,
1661                         CorDebugBlockingObject,
1662                         ICorDebugBlockingObjectEnum,
1663                         IdentityConvert<CorDebugBlockingObject> > CordbBlockingObjectEnumerator;
1664
1665 // Template classes must be fully defined rather than just declared in the header
1666 #include "rsenumerator.hpp"
1667
1668
1669 typedef CordbEnumerator<COR_SEGMENT,
1670                         COR_SEGMENT,
1671                         ICorDebugHeapSegmentEnum,
1672                         IdentityConvert<COR_SEGMENT> > CordbHeapSegmentEnumerator;
1673
1674 typedef CordbEnumerator<CorDebugExceptionObjectStackFrame,
1675                         CorDebugExceptionObjectStackFrame,
1676                         ICorDebugExceptionObjectCallStackEnum,
1677                         IdentityConvert<CorDebugExceptionObjectStackFrame> > CordbExceptionObjectCallStackEnumerator;
1678
1679 typedef CordbEnumerator<RsGuidToTypeMapping,
1680                         CorDebugGuidToTypeMapping,
1681                         ICorDebugGuidToTypeEnum,
1682                         GuidToTypeMappingConvert > CordbGuidToTypeEnumerator;
1683
1684 typedef CordbEnumerator<RSSmartPtr<CordbVariableHome>,
1685                         ICorDebugVariableHome*,
1686                         ICorDebugVariableHomeEnum,
1687                         QueryInterfaceConvert<RSSmartPtr<CordbVariableHome>, ICorDebugVariableHome> > CordbVariableHomeEnumerator;
1688
1689 // ----------------------------------------------------------------------------
1690 // Hash table for CordbBase objects.
1691 // - Uses Internal AddRef/Release (not external)
1692 // - Templatize for type-safety w/ Cordb objects
1693 // - Many hashtables are implicitly protected by a lock. For debug-only, we
1694 //   explicitly associate w/ an optional RSLock and assert that lock is held on access.
1695 // ----------------------------------------------------------------------------
1696
1697 struct CordbHashEntry
1698 {
1699     FREEHASHENTRY entry;
1700     CordbBase *pBase;
1701 };
1702
1703 class CordbHashTable : private CHashTableAndData<CNewDataNoThrow>
1704 {
1705 private:
1706     bool    m_initialized;
1707     SIZE_T  m_count;
1708
1709     BOOL Cmp(SIZE_T k1, const HASHENTRY * pc2)
1710     {
1711         LIMITED_METHOD_CONTRACT;
1712
1713         return ((ULONG_PTR)k1) != (reinterpret_cast<const CordbHashEntry *>(pc2))->pBase->m_id;
1714     }
1715
1716     ULONG HASH(ULONG_PTR id)
1717     {
1718         return (ULONG)(id);
1719     }
1720
1721     SIZE_T KEY(UINT_PTR id)
1722     {
1723         return (SIZE_T)id;
1724     }
1725
1726 public:
1727     bool IsInitialized();
1728
1729 #ifndef DACCESS_COMPILE
1730     CordbHashTable(ULONG size)
1731     : CHashTableAndData<CNewDataNoThrow>(size), m_initialized(false), m_count(0)
1732     {
1733 #ifdef _DEBUG
1734     m_pDbgLock = NULL;
1735     m_dbgChangeCount = 0;
1736 #endif
1737     }
1738     virtual ~CordbHashTable();
1739
1740 #ifdef _DEBUG
1741     // CordbHashTables may be protected by a lock. For debug-builds, we can associate
1742     // the hash w/ that lock and then assert if it's not held.
1743     void DebugSetRSLock(RSLock * pLock)
1744     {
1745         m_pDbgLock = pLock;
1746     }
1747     int GetChangeCount() { return m_dbgChangeCount; }
1748 private:
1749     void AssertIsProtected();
1750
1751     // Increment the Change count. This can be used to check if the hashtable changes while being enumerated.
1752     void DbgIncChangeCount() { m_dbgChangeCount++; }
1753
1754     int m_dbgChangeCount;
1755     RSLock * m_pDbgLock;
1756 #else
1757     // RSLock association is a no-op on free builds.
1758     void AssertIsProtected() { };
1759     void DbgIncChangeCount() { };
1760 #endif // _DEBUG
1761
1762 public:
1763
1764
1765 #endif
1766
1767     ULONG32 GetCount()
1768     {
1769         return ((ULONG32)m_count);
1770     }
1771
1772     // These operators are unsafe b/c they have no typesafety.
1773     // Use a derived CordbSafeHashTable<T> instead.
1774     HRESULT UnsafeAddBase(CordbBase *pBase);
1775     HRESULT UnsafeSwapBase(CordbBase* pBaseOld, CordbBase* pBaseNew);
1776     CordbBase *UnsafeGetBase(ULONG_PTR id, BOOL fFab = TRUE);
1777     CordbBase *UnsafeRemoveBase(ULONG_PTR id);
1778
1779     CordbBase *UnsafeFindFirst(HASHFIND *find);
1780     CordbBase *UnsafeFindNext(HASHFIND *find);
1781
1782     // Unlocked versions don't assert that the lock us held.
1783     CordbBase *UnsafeUnlockedFindFirst(HASHFIND *find);
1784     CordbBase *UnsafeUnlockedFindNext(HASHFIND *find);
1785
1786 };
1787
1788
1789 // Typesafe wrapper around a normal hash table
1790 // T is expected to be a derived clas of CordbBase
1791 // Note that this still isn't fully typesafe.  Ideally we'd take a strongly-typed key
1792 // instead of UINT_PTR (the type could have a fixed relationship to T, or could be
1793 // an additional template argument like standard template hash tables like std::hash_map<K,V>)
1794 template <class T>
1795 class CordbSafeHashTable : public CordbHashTable
1796 {
1797 public:
1798 #ifndef DACCESS_COMPILE
1799     CordbSafeHashTable<T>(ULONG size) : CordbHashTable(size)
1800     {
1801     }
1802 #endif
1803     // Typesafe wrappers
1804     HRESULT AddBase(T * pBase) { return UnsafeAddBase(pBase); }
1805
1806     // Either add (eg, future cals to GetBase will succeed) or throw. 
1807     void AddBaseOrThrow(T * pBase)
1808     {
1809         HRESULT hr = AddBase(pBase);
1810         IfFailThrow(hr);
1811     }
1812     HRESULT SwapBase(T* pBaseOld, T* pBaseNew) { return UnsafeSwapBase(pBaseOld, pBaseNew); }
1813     // Move the function definition of GetBase to rspriv.inl to work around gcc 2.9.5 warnings
1814     T* GetBase(ULONG_PTR id, BOOL fFab = TRUE);
1815     T* GetBaseOrThrow(ULONG_PTR id, BOOL fFab = TRUE);
1816
1817     T* RemoveBase(ULONG_PTR id) { return static_cast<T*>(UnsafeRemoveBase(id)); }
1818
1819     T* FindFirst(HASHFIND *find) { return static_cast<T*>(UnsafeFindFirst(find)); }
1820     T* FindNext(HASHFIND *find)  { return static_cast<T*>(UnsafeFindNext(find)); }
1821
1822     // Neuter all items and clear
1823     void NeuterAndClear(RSLock * pLock);
1824
1825     void CopyToArray(RSPtrArray<T> * pArray);
1826     void TransferToArray(RSPtrArray<T> * pArray);
1827 };
1828
1829
1830 class CordbHashTableEnum : public CordbBase,
1831 public ICorDebugProcessEnum,
1832 public ICorDebugBreakpointEnum,
1833 public ICorDebugStepperEnum,
1834 public ICorDebugThreadEnum,
1835 public ICorDebugModuleEnum,
1836 public ICorDebugAppDomainEnum,
1837 public ICorDebugAssemblyEnum
1838 {
1839     // Private ctors. Use build function to access.
1840     CordbHashTableEnum(
1841         CordbBase * pOwnerObj, 
1842         NeuterList * pOwnerList, 
1843         CordbHashTable *table,
1844         const _GUID &id);
1845
1846 public:
1847     static void BuildOrThrow(
1848         CordbBase * pOwnerObj, 
1849         NeuterList * pOwnerList, 
1850         CordbHashTable *table,
1851         const _GUID &id,
1852         RSInitHolder<CordbHashTableEnum> * pHolder);
1853
1854     CordbHashTableEnum(CordbHashTableEnum *cloneSrc);
1855
1856     ~CordbHashTableEnum();
1857     virtual void Neuter();
1858
1859
1860 #ifdef _DEBUG
1861     // For debugging (asserts, logging, etc) provide a pretty name (this is 1:1 w/ the VTable)
1862     virtual const char * DbgGetName() { return "CordbHashTableEnum"; };
1863 #endif
1864
1865
1866     HRESULT Next(ULONG celt, CordbBase *bases[], ULONG *pceltFetched);
1867
1868     //-----------------------------------------------------------
1869     // IUnknown
1870     //-----------------------------------------------------------
1871
1872     ULONG STDMETHODCALLTYPE AddRef()
1873     {
1874         return (BaseAddRef());
1875     }
1876     ULONG STDMETHODCALLTYPE Release()
1877     {
1878         return (BaseRelease());
1879     }
1880     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
1881
1882     //-----------------------------------------------------------
1883     // ICorDebugEnum
1884     //-----------------------------------------------------------
1885
1886     COM_METHOD Skip(ULONG celt);
1887     COM_METHOD Reset();
1888     COM_METHOD Clone(ICorDebugEnum **ppEnum);
1889     COM_METHOD GetCount(ULONG *pcelt);
1890
1891     //-----------------------------------------------------------
1892     // ICorDebugProcessEnum
1893     //-----------------------------------------------------------
1894
1895     COM_METHOD Next(ULONG celt, ICorDebugProcess *processes[],
1896                     ULONG *pceltFetched)
1897     {
1898         VALIDATE_POINTER_TO_OBJECT_ARRAY(processes, ICorDebugProcess *,
1899             celt, true, true);
1900         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1901
1902         return (Next(celt, (CordbBase **)processes, pceltFetched));
1903     }
1904
1905     //-----------------------------------------------------------
1906     // ICorDebugBreakpointEnum
1907     //-----------------------------------------------------------
1908
1909     COM_METHOD Next(ULONG celt, ICorDebugBreakpoint *breakpoints[],
1910                     ULONG *pceltFetched)
1911     {
1912         VALIDATE_POINTER_TO_OBJECT_ARRAY(breakpoints, ICorDebugBreakpoint *,
1913             celt, true, true);
1914         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1915
1916         return (Next(celt, (CordbBase **)breakpoints, pceltFetched));
1917     }
1918
1919     //-----------------------------------------------------------
1920     // ICorDebugStepperEnum
1921     //-----------------------------------------------------------
1922
1923     COM_METHOD Next(ULONG celt, ICorDebugStepper *steppers[],
1924                     ULONG *pceltFetched)
1925     {
1926         VALIDATE_POINTER_TO_OBJECT_ARRAY(steppers, ICorDebugStepper *,
1927             celt, true, true);
1928         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1929
1930         return (Next(celt, (CordbBase **)steppers, pceltFetched));
1931     }
1932
1933     //-----------------------------------------------------------
1934     // ICorDebugThreadEnum
1935     //-----------------------------------------------------------
1936
1937     COM_METHOD Next(ULONG celt, ICorDebugThread *threads[],
1938                     ULONG *pceltFetched)
1939     {
1940         VALIDATE_POINTER_TO_OBJECT_ARRAY(threads, ICorDebugThread *,
1941             celt, true, true);
1942         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1943
1944         return (Next(celt, (CordbBase **)threads, pceltFetched));
1945     }
1946
1947     //-----------------------------------------------------------
1948     // ICorDebugModuleEnum
1949     //-----------------------------------------------------------
1950
1951     COM_METHOD Next(ULONG celt, ICorDebugModule *modules[],
1952                     ULONG *pceltFetched)
1953     {
1954         VALIDATE_POINTER_TO_OBJECT_ARRAY(modules, ICorDebugModule *,
1955             celt, true, true);
1956         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1957
1958         return (Next(celt, (CordbBase **)modules, pceltFetched));
1959     }
1960
1961     //-----------------------------------------------------------
1962     // ICorDebugAppDomainEnum
1963     //-----------------------------------------------------------
1964
1965     COM_METHOD Next(ULONG celt, ICorDebugAppDomain *appdomains[],
1966                     ULONG *pceltFetched)
1967     {
1968         VALIDATE_POINTER_TO_OBJECT_ARRAY(appdomains, ICorDebugAppDomain *,
1969             celt, true, true);
1970         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1971
1972         return (Next(celt, (CordbBase **)appdomains, pceltFetched));
1973     }
1974     //-----------------------------------------------------------
1975     // ICorDebugAssemblyEnum
1976     //-----------------------------------------------------------
1977
1978     COM_METHOD Next(ULONG celt, ICorDebugAssembly *assemblies[],
1979                     ULONG *pceltFetched)
1980     {
1981         VALIDATE_POINTER_TO_OBJECT_ARRAY(assemblies, ICorDebugAssembly *,
1982             celt, true, true);
1983         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1984
1985         return (Next(celt, (CordbBase **)assemblies, pceltFetched));
1986     }
1987 private:
1988     // Owning object is our link to the CordbProcess* tree. Never null until we're neutered.
1989     // NeuterList is related to the owning object. Need to cache it so that we can pass it on
1990     // to our clones.
1991     CordbBase *     m_pOwnerObj; // provides us w/ a CordbProcess*
1992     NeuterList *    m_pOwnerNeuterList;
1993
1994
1995     CordbHashTable *m_table;
1996     bool            m_started;
1997     bool            m_done;
1998     HASHFIND        m_hashfind;
1999     REFIID          m_guid;
2000     ULONG           m_iCurElt;
2001     ULONG           m_count;
2002     BOOL            m_fCountInit;
2003
2004 #ifdef _DEBUG
2005     // timestampt of hashtable when we start enumerating it. Useful for detecting if the table
2006     // changes underneath us.
2007     int             m_DbgChangeCount;
2008     void AssertValid();
2009 #else
2010     void AssertValid() { }
2011 #endif
2012
2013 private:
2014     //These factor code between Next & Skip
2015     HRESULT PrepForEnum(CordbBase **pBase);
2016
2017     // Note that the set of types advanced by Pre & by Post are disjoint, and
2018     // that the union of these two sets are all possible types enuerated by
2019     // the CordbHashTableEnum.
2020     HRESULT AdvancePreAssign(CordbBase **pBase);
2021     HRESULT AdvancePostAssign(CordbBase **pBase,
2022                               CordbBase     **b,
2023                               CordbBase   **bEnd);
2024
2025     // This factors some code that initializes the module enumerator.
2026     HRESULT SetupModuleEnum();
2027
2028 };
2029
2030
2031 //-----------------------------------------------------------------------------
2032 // Neuter List
2033 // Dtors can be called at any time (whenever Cordbg calls Release, which is outside
2034 // of our control), so we never want to do significant work in a dtor
2035 // (this includes sending IPC events + neutering).
2036 // So objects can queue themselves up to be neutered at a safe time.
2037 // 
2038 // Items in a NeuterList should only contain state in the Right-Side.
2039 // If the item holds resources in the left-side, it should be placed on a
2040 // code:LeftSideResourceCleanupList 
2041 //-----------------------------------------------------------------------------
2042 class NeuterList
2043 {
2044 public:
2045     NeuterList();
2046     ~NeuterList();
2047
2048     // Add an object to be neutered.
2049     // Anybody calls this to add themselves to the list.
2050     // This will add it to the list and maintain an internal reference to it.
2051     void Add(CordbProcess * pProcess, CordbBase * pObject);
2052
2053     // Add w/o checking for safety. Should only be used by Process-list enum.
2054     void UnsafeAdd(CordbProcess * pProcess, CordbBase * pObject);
2055
2056     // Neuter everything on the list.
2057     // This should only be called by the "owner", but we can't really enforce that.
2058     // This will release all internal references and empty the list.
2059     void NeuterAndClear(CordbProcess * pProcess);
2060
2061     // Sweep for all objects that are marked as 'm_fNeuterAtWill'.
2062     // Neuter and remove these.
2063     void SweepAllNeuterAtWillObjects(CordbProcess * pProcess);
2064
2065 protected:
2066     struct Node
2067     {
2068         RSSmartPtr<CordbBase> m_pObject;
2069         Node * m_pNext;
2070     };
2071
2072     // Manipulating the list is done under the Process lock.
2073     Node * m_pHead;
2074 };
2075
2076 //-----------------------------------------------------------------------------
2077 // This list is for objects that hold left-side resources. 
2078 // If the object does not hold left-side resources, it can be placed on a
2079 // code:NeuterList
2080 //-----------------------------------------------------------------------------
2081 class LeftSideResourceCleanupList : public NeuterList
2082 {
2083 public:
2084     // dispose everything contained in the list by calling SafeDispose() on each element
2085     void SweepNeuterLeftSideResources(CordbProcess * pProcess);
2086     void NeuterLeftSideResourcesAndClear(CordbProcess * pProcess);
2087 };
2088
2089 //-------------------------------------------------------------------------
2090 //
2091 // Optional<T>
2092 // Stores a value along with a bit indicating whether the value is valid.
2093 //
2094 // This is particularly useful for LS data read via DAC.  We need to gracefully
2095 // handle missing data, and we may want to track independent pieces of data
2096 // separately (often with lazy initialization).  It's essential that we can't
2097 // easily lose track of whether the data has been cached yet or not.  So 
2098 // rather than have extra "isValid" bools everywhere, we use this class to
2099 // encapsulate the validity bit in with the data, and ASSERT that it is true
2100 // whenever reading out the data.
2101 // Note that the client must still remember to call GetValue only when HasValue 
2102 // is true.  Since C++ doesn't have type-safe sum types, we can't enforce this
2103 // explicitly at compile time (ML-style datatypes and pattern matching is perfect
2104 // for this).
2105 //
2106 // Note that we could consider adding some operator overloads to make using 
2107 // instances of this class more transparent.  Experience will tell if this
2108 // is a good idea or not.
2109 //
2110 template <typename T>
2111 class Optional
2112 {
2113 public:
2114     // By default, initialize to invalid 
2115     Optional() : m_fHasValue(false), m_value(T()) {}
2116
2117     // Allow implicit initialization from a value (for copyable T)
2118     Optional(const T& val) : m_fHasValue(true), m_value(val) {}
2119
2120     // Returns true if a value has been stored
2121     bool HasValue() const    { return m_fHasValue; }
2122
2123     // Extract the value.  Can only be called when HasValue is true.
2124     const T& GetValue()        { _ASSERTE(m_fHasValue); return m_value; }
2125
2126     // Get a writable pointer to the value structure, for filling in uncopyable data structures
2127     T * GetValueAddr() { return &m_value; }
2128
2129     // Explicitly mark this object as having a value (for use after writing to it directly using
2130     // GetValueAddr.  Not necessary for simple/primitive types).
2131     void SetHasValue() { m_fHasValue = true; }
2132
2133     // Also gets compiler-default copy constructor and assignment operator if T has them
2134
2135 private:
2136     bool m_fHasValue;
2137     T m_value;
2138 };
2139
2140
2141 /* ------------------------------------------------------------------------- *
2142  * Cordb class
2143  * ------------------------------------------------------------------------- */
2144
2145 class Cordb : public CordbBase, public ICorDebug, public ICorDebugRemote
2146 {
2147 public:
2148     Cordb(CorDebugInterfaceVersion iDebuggerVersion);
2149     virtual ~Cordb();
2150     virtual void Neuter();
2151
2152
2153
2154 #ifdef _DEBUG_IMPL
2155     virtual const char * DbgGetName() { return "Cordb"; }
2156
2157     // Under Debug, we keep some extra state for tracking leaks. The goal is that
2158     // we can assert that we aren't leaking internal refs. We'd like to assert that
2159     // we're not leaking external refs, but since we can't force Cordbg to release,
2160     // we can't really assert that.
2161     // So the idea is that when Cordbg has released its last Cordb object, that
2162     // all internal references have been released.
2163     // Unfortunately, certain CordbBase objects are unrooted and thus we have no
2164     // good time to neuter them and clean up any internal references they may hold.
2165     // So we keep count of those guys too.
2166     static LONG s_DbgMemTotalOutstandingCordb;
2167     static LONG s_DbgMemTotalOutstandingInternalRefs;
2168 #endif
2169
2170     //
2171     // Turn this on to enable an array which will contain all objects that have
2172     // not been completely released.
2173     //
2174     // #define TRACK_OUTSTANDING_OBJECTS 1
2175
2176 #ifdef TRACK_OUTSTANDING_OBJECTS
2177
2178 #define MAX_TRACKED_OUTSTANDING_OBJECTS 256
2179     static void *Cordb::s_DbgMemOutstandingObjects[MAX_TRACKED_OUTSTANDING_OBJECTS];
2180     static LONG Cordb::s_DbgMemOutstandingObjectMax;
2181 #endif
2182
2183
2184     //-----------------------------------------------------------
2185     // IUnknown
2186     //-----------------------------------------------------------
2187
2188     ULONG STDMETHODCALLTYPE AddRef()
2189     {
2190         return (BaseAddRef());
2191     }
2192     ULONG STDMETHODCALLTYPE Release()
2193     {
2194         return (BaseRelease());
2195     }
2196     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
2197
2198     //-----------------------------------------------------------
2199     // ICorDebug
2200     //-----------------------------------------------------------
2201
2202     HRESULT SetTargetCLR(HMODULE hmodTargetCLR);
2203
2204     COM_METHOD Initialize();
2205     COM_METHOD Terminate();
2206     COM_METHOD SetManagedHandler(ICorDebugManagedCallback *pCallback);
2207     COM_METHOD SetUnmanagedHandler(ICorDebugUnmanagedCallback *pCallback);
2208     COM_METHOD CreateProcess(LPCWSTR lpApplicationName,
2209                              __in_z LPWSTR lpCommandLine,
2210                              LPSECURITY_ATTRIBUTES lpProcessAttributes,
2211                              LPSECURITY_ATTRIBUTES lpThreadAttributes,
2212                              BOOL bInheritHandles,
2213                              DWORD dwCreationFlags,
2214                              PVOID lpEnvironment,
2215                              LPCWSTR lpCurrentDirectory,
2216                              LPSTARTUPINFOW lpStartupInfo,
2217                              LPPROCESS_INFORMATION lpProcessInformation,
2218                              CorDebugCreateProcessFlags debuggingFlags,
2219                              ICorDebugProcess **ppProcess);
2220     COM_METHOD DebugActiveProcess(DWORD dwProcessId, BOOL fWin32Attach, ICorDebugProcess **ppProcess);
2221     COM_METHOD EnumerateProcesses(ICorDebugProcessEnum **ppProcess);
2222     COM_METHOD GetProcess(DWORD dwProcessId, ICorDebugProcess **ppProcess);
2223     COM_METHOD CanLaunchOrAttach(DWORD dwProcessId, BOOL win32DebuggingEnabled);
2224
2225     //-----------------------------------------------------------
2226     // CorDebug
2227     //-----------------------------------------------------------
2228
2229     static COM_METHOD CreateObjectV1(REFIID id, void **object);
2230 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
2231     static COM_METHOD CreateObjectTelesto(REFIID id, void ** pObject);
2232 #endif // FEATURE_DBGIPC_TRANSPORT_DI
2233     static COM_METHOD CreateObject(CorDebugInterfaceVersion iDebuggerVersion, REFIID id, void **object);
2234
2235     //-----------------------------------------------------------
2236     // ICorDebugRemote
2237     //-----------------------------------------------------------
2238
2239     COM_METHOD CreateProcessEx(ICorDebugRemoteTarget * pRemoteTarget,
2240                                LPCWSTR lpApplicationName,
2241                                __in_z LPWSTR lpCommandLine,
2242                                LPSECURITY_ATTRIBUTES lpProcessAttributes,
2243                                LPSECURITY_ATTRIBUTES lpThreadAttributes,
2244                                BOOL bInheritHandles,
2245                                DWORD dwCreationFlags,
2246                                PVOID lpEnvironment,
2247                                LPCWSTR lpCurrentDirectory,
2248                                LPSTARTUPINFOW lpStartupInfo,
2249                                LPPROCESS_INFORMATION lpProcessInformation,
2250                                CorDebugCreateProcessFlags debuggingFlags,
2251                                ICorDebugProcess ** ppProcess);
2252     
2253     COM_METHOD DebugActiveProcessEx(ICorDebugRemoteTarget * pRemoteTarget, 
2254                                     DWORD dwProcessId, 
2255                                     BOOL fWin32Attach, 
2256                                     ICorDebugProcess ** ppProcess);
2257     
2258
2259     //-----------------------------------------------------------
2260     // Methods not exposed via a COM interface.
2261     //-----------------------------------------------------------
2262
2263     HRESULT CreateProcessCommon(ICorDebugRemoteTarget * pRemoteTarget,
2264                                 LPCWSTR lpApplicationName,
2265                                 __in_z LPWSTR lpCommandLine,
2266                                 LPSECURITY_ATTRIBUTES lpProcessAttributes,
2267                                 LPSECURITY_ATTRIBUTES lpThreadAttributes,
2268                                 BOOL bInheritHandles,
2269                                 DWORD dwCreationFlags,
2270                                 PVOID lpEnvironment,
2271                                 LPCWSTR lpCurrentDirectory,
2272                                 LPSTARTUPINFOW lpStartupInfo,
2273                                 LPPROCESS_INFORMATION lpProcessInformation,
2274                                 CorDebugCreateProcessFlags debuggingFlags,
2275                                 ICorDebugProcess **ppProcess);
2276
2277     HRESULT DebugActiveProcessCommon(ICorDebugRemoteTarget * pRemoteTarget, DWORD id, BOOL win32Attach, ICorDebugProcess **ppProcess);
2278
2279     void EnsureCanLaunchOrAttach(BOOL fWin32DebuggingEnabled);
2280
2281     void EnsureAllowAnotherProcess();
2282     void AddProcess(CordbProcess* process);
2283     void RemoveProcess(CordbProcess* process);
2284     CordbSafeHashTable<CordbProcess> *GetProcessList();
2285
2286     void LockProcessList();
2287     void UnlockProcessList();
2288
2289     #ifdef _DEBUG
2290     bool ThreadHasProcessListLock();
2291     #endif
2292
2293
2294     HRESULT SendIPCEvent(CordbProcess * pProcess,
2295                          DebuggerIPCEvent * pEvent,
2296                          SIZE_T eventSize);
2297
2298     void ProcessStateChanged();
2299
2300     HRESULT WaitForIPCEventFromProcess(CordbProcess* process,
2301                                        CordbAppDomain *appDomain,
2302                                        DebuggerIPCEvent* event);
2303
2304     //-----------------------------------------------------------
2305     // Data members
2306     //-----------------------------------------------------------
2307
2308 public:
2309     RSExtSmartPtr<ICorDebugManagedCallback>    m_managedCallback;
2310     RSExtSmartPtr<ICorDebugManagedCallback2>   m_managedCallback2;
2311     RSExtSmartPtr<ICorDebugManagedCallback3>   m_managedCallback3;
2312     RSExtSmartPtr<ICorDebugUnmanagedCallback>  m_unmanagedCallback;
2313
2314     CordbRCEventThread*         m_rcEventThread;
2315
2316     CorDebugInterfaceVersion    GetDebuggerVersion() const;
2317
2318         HMODULE GetTargetCLR() { return m_targetCLR; }
2319
2320 private:
2321     bool IsCreateProcessSupported();
2322     bool IsInteropDebuggingSupported();
2323     void CheckCompatibility();
2324
2325     CordbSafeHashTable<CordbProcess> m_processes;
2326
2327     // List to track outstanding CordbProcessEnum objects.
2328     NeuterList                  m_pProcessEnumList;
2329
2330     RSLock                      m_processListMutex;
2331     BOOL                        m_initialized;
2332
2333     // This is the version of the ICorDebug APIs that the debugger believes it's consuming.
2334     CorDebugInterfaceVersion    m_debuggerSpecifiedVersion;
2335
2336 //Note - this code could be useful outside coresystem, but keeping the change localized
2337 // because we are late in the win8 release
2338         HMODULE m_targetCLR;
2339 };
2340
2341
2342
2343
2344 /* ------------------------------------------------------------------------- *
2345  * AppDomain class
2346  * ------------------------------------------------------------------------- */
2347
2348 // Provides the implementation for ICorDebugAppDomain, ICorDebugAppDomain2, 
2349 // and ICorDebugAppDomain3
2350 class CordbAppDomain : public CordbBase, 
2351                         public ICorDebugAppDomain, 
2352                         public ICorDebugAppDomain2,
2353                         public ICorDebugAppDomain3,
2354                         public ICorDebugAppDomain4
2355 {
2356 public:
2357     // Create a CordbAppDomain object based on a pointer to the AppDomain instance in the CLR 
2358     CordbAppDomain(CordbProcess *  pProcess,
2359                    VMPTR_AppDomain vmAppDomain);
2360
2361     virtual ~CordbAppDomain();
2362
2363     virtual void Neuter();
2364
2365     using CordbBase::GetProcess;
2366
2367 #ifdef _DEBUG
2368     virtual const char * DbgGetName() { return "CordbAppDomain"; }
2369 #endif
2370
2371
2372     //-----------------------------------------------------------
2373     // IUnknown
2374     //-----------------------------------------------------------
2375
2376     ULONG STDMETHODCALLTYPE AddRef()
2377     {
2378         return (BaseAddRef());
2379     }
2380     ULONG STDMETHODCALLTYPE Release()
2381     {
2382         return (BaseRelease());
2383     }
2384     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
2385
2386     //-----------------------------------------------------------
2387     // ICorDebugController
2388     //-----------------------------------------------------------
2389
2390     COM_METHOD Stop(DWORD dwTimeout);
2391     COM_METHOD Continue(BOOL fIsOutOfBand);
2392     COM_METHOD IsRunning(BOOL * pbRunning);
2393     COM_METHOD HasQueuedCallbacks(ICorDebugThread * pThread, 
2394                                   BOOL *            pbQueued);
2395     COM_METHOD EnumerateThreads(ICorDebugThreadEnum ** ppThreads);
2396     COM_METHOD SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread * pExceptThisThread);
2397     
2398     // Deprecated, returns E_NOTIMPL
2399     COM_METHOD Detach();
2400
2401     COM_METHOD Terminate(unsigned int exitCode);
2402
2403     COM_METHOD CanCommitChanges(
2404         ULONG                              cSnapshots,
2405         ICorDebugEditAndContinueSnapshot * pSnapshots[],
2406         ICorDebugErrorInfoEnum **          pError);
2407
2408     COM_METHOD CommitChanges(
2409         ULONG                              cSnapshots,
2410         ICorDebugEditAndContinueSnapshot * pSnapshots[],
2411         ICorDebugErrorInfoEnum **          pError);
2412
2413     //-----------------------------------------------------------
2414     // ICorDebugAppDomain
2415     //-----------------------------------------------------------
2416     /*
2417      * GetProcess returns the process containing the app domain
2418      */
2419
2420     COM_METHOD GetProcess(ICorDebugProcess ** ppProcess);
2421
2422     /*
2423      * EnumerateAssemblies enumerates all assemblies in the app domain
2424      */
2425
2426     COM_METHOD EnumerateAssemblies(ICorDebugAssemblyEnum ** ppAssemblies);
2427
2428     COM_METHOD GetModuleFromMetaDataInterface(IUnknown *         pIMetaData,
2429                                               ICorDebugModule ** ppModule);
2430     /*
2431      * EnumerateBreakpoints returns an enum of all active breakpoints
2432      * in the app domain.  This includes all types of breakpoints :
2433      * function breakpoints, data breakpoints, etc.
2434      */
2435
2436     COM_METHOD EnumerateBreakpoints(ICorDebugBreakpointEnum ** ppBreakpoints);
2437
2438     /*
2439      * EnumerateSteppers returns an enum of all active steppers in the app domain.
2440      */
2441
2442     COM_METHOD EnumerateSteppers(ICorDebugStepperEnum ** ppSteppers);
2443
2444     // Deprecated, always returns true.
2445     COM_METHOD IsAttached(BOOL * pfAttached);
2446
2447     // Returns the friendly name of the AppDomain
2448     COM_METHOD GetName(ULONG32   cchName,
2449                        ULONG32 * pcchName,
2450                        __out_ecount_part_opt(cchName, *pcchName) WCHAR     szName[]);
2451
2452     /*
2453      * GetObject returns the runtime app domain object.
2454      * Note:   This method is not yet implemented.
2455      */
2456
2457     COM_METHOD GetObject(ICorDebugValue ** ppObject);
2458
2459     // Deprecated, does nothing
2460     COM_METHOD Attach();
2461     COM_METHOD GetID(ULONG32 * pId);
2462
2463     //-----------------------------------------------------------
2464     // ICorDebugAppDomain2 APIs
2465     //-----------------------------------------------------------
2466     COM_METHOD GetArrayOrPointerType(CorElementType   elementType,
2467                                      ULONG32          nRank,
2468                                      ICorDebugType *  pTypeArg,
2469                                      ICorDebugType ** ppResultType);
2470
2471     COM_METHOD GetFunctionPointerType(ULONG32          cTypeArgs,
2472                                       ICorDebugType *  rgpTypeArgs[],
2473                                       ICorDebugType ** ppResultType);
2474
2475     //-----------------------------------------------------------
2476     // ICorDebugAppDomain3 APIs
2477     //-----------------------------------------------------------
2478     COM_METHOD GetCachedWinRTTypesForIIDs(
2479                                             ULONG32               cGuids,
2480                                         GUID                * guids,
2481                                         ICorDebugTypeEnum * * ppTypesEnum);
2482
2483     COM_METHOD GetCachedWinRTTypes(
2484                                                 ICorDebugGuidToTypeEnum * * ppType);
2485
2486     //-----------------------------------------------------------
2487     // ICorDebugAppDomain4
2488     //-----------------------------------------------------------
2489     COM_METHOD GetObjectForCCW(CORDB_ADDRESS ccwPointer, ICorDebugValue **ppManagedObject);
2490
2491     // Get the VMPTR for this appdomain.
2492     VMPTR_AppDomain GetADToken() { return m_vmAppDomain; }
2493
2494     // Given a metadata interface, find the module in this appdomain that matches it.
2495     CordbModule * GetModuleFromMetaDataInterface(IUnknown *pIMetaData);
2496
2497     // Lookup a module from the cache.  Create and to the cache if needed.
2498     CordbModule * LookupOrCreateModule(VMPTR_Module vmModuleToken, VMPTR_DomainFile vmDomainFileToken);
2499     
2500     // Lookup a module from the cache.  Create and to the cache if needed.
2501     CordbModule * LookupOrCreateModule(VMPTR_DomainFile vmDomainFileToken);
2502
2503     // Callback from DAC for module enumeration
2504     static void ModuleEnumerationCallback(VMPTR_DomainFile vmModule, void * pUserData);
2505
2506     // Use DAC to add any modules for this assembly.
2507     void PrepopulateModules();
2508
2509     void InvalidateName() { m_strAppDomainName.Clear(); }
2510
2511 public:
2512     ULONG               m_AppDomainId;
2513
2514     CordbAssembly * LookupOrCreateAssembly(VMPTR_DomainAssembly vmDomainAssembly);
2515     CordbAssembly * LookupOrCreateAssembly(VMPTR_Assembly vmAssembly);
2516     void RemoveAssemblyFromCache(VMPTR_DomainAssembly vmDomainAssembly);
2517     
2518
2519     CordbSafeHashTable<CordbBreakpoint>  m_breakpoints;
2520
2521     // Unique objects that represent the use of some
2522                                          // basic ELEMENT_TYPE's as type parameters.  These
2523                                          // are shared acrosss the entire process.  We could
2524                                          // go and try to find the classes corresponding to these
2525                                          // element types but it seems simpler just to keep
2526                                          // them as special cases.
2527     CordbSafeHashTable<CordbType>        m_sharedtypes;   
2528
2529     CordbAssembly * CacheAssembly(VMPTR_DomainAssembly vmDomainAssembly);
2530     CordbAssembly * CacheAssembly(VMPTR_Assembly vmAssembly);
2531
2532
2533     // Cache of modules in this appdomain. In the VM, modules live in an assembly.
2534     // This cache lives on the appdomain because we generally want to do appdomain (or process)
2535     // wide lookup.
2536     // This is indexed by VMPTR_DomainFile, which has appdomain affinity.
2537     // This is populated by code:CordbAppDomain::LookupOrCreateModule (which may be invoked
2538     // anytime the RS gets hold of a VMPTR), and are removed at the unload event.
2539     CordbSafeHashTable<CordbModule>      m_modules;
2540 private:
2541     // Cache of assemblies in this appdomain. 
2542     // This is indexed by VMPTR_DomainAssembly, which has appdomain affinity.
2543     // This is populated by code:CordbAppDomain::LookupOrCreateAssembly (which may be invoked
2544     // anytime the RS gets hold of a VMPTR), and are removed at the unload event.
2545     CordbSafeHashTable<CordbAssembly>    m_assemblies;
2546
2547     static void AssemblyEnumerationCallback(VMPTR_DomainAssembly vmDomainAssembly, void * pThis);
2548     void PrepopulateAssembliesOrThrow();
2549
2550     // Use DAC to refresh our name
2551     HRESULT RefreshName();
2552
2553     StringCopyHolder    m_strAppDomainName;
2554
2555     NeuterList          m_TypeNeuterList;  // List of types owned by this AppDomain.
2556
2557     // List of Sweepable objects owned by this AppDomain.
2558     // This includes some objects taht hold resources in the left-side (mainly
2559     // as CordbHandleValue, see code:CordbHandleValue::Dispose), as well as:
2560     // - Cordb*Value objects that survive across continues and have appdomain affinity.
2561     LeftSideResourceCleanupList          m_SweepableNeuterList;  
2562
2563     VMPTR_AppDomain     m_vmAppDomain;
2564 public:
2565     // The "Long" exit list is for items that don't get neutered until the appdomain exits.
2566     // The "Sweepable" exit list is for items that may be neuterable sooner than AD exit.
2567     // By splitting out the list, we can just try to sweep the "Sweepable" list and we
2568     // don't waste any time sweeping things on the "Long" list that aren't neuterable anyways.
2569     NeuterList * GetLongExitNeuterList() { return &m_TypeNeuterList; }
2570     LeftSideResourceCleanupList * GetSweepableExitNeuterList() { return &m_SweepableNeuterList; }
2571
2572     void AddToTypeList(CordbBase *pObject);
2573
2574 };
2575
2576
2577 /* ------------------------------------------------------------------------- *
2578  * Assembly class
2579  * ------------------------------------------------------------------------- */
2580
2581 class CordbAssembly : public CordbBase, public ICorDebugAssembly, ICorDebugAssembly2
2582 {
2583 public:
2584     CordbAssembly(CordbAppDomain *      pAppDomain,
2585                   VMPTR_Assembly        vmAssembly,
2586                   VMPTR_DomainAssembly  vmDomainAssembly);
2587     virtual ~CordbAssembly();
2588     virtual void Neuter();
2589
2590     using CordbBase::GetProcess;
2591
2592 #ifdef _DEBUG
2593     virtual const char * DbgGetName() { return "CordbAssembly"; }
2594 #endif
2595
2596
2597     //-----------------------------------------------------------
2598     // IUnknown
2599     //-----------------------------------------------------------
2600
2601     ULONG STDMETHODCALLTYPE AddRef()
2602     {
2603         return (BaseAddRef());
2604     }
2605     ULONG STDMETHODCALLTYPE Release()
2606     {
2607         return (BaseRelease());
2608     }
2609     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
2610
2611     //-----------------------------------------------------------
2612     // ICorDebugAssembly
2613     //-----------------------------------------------------------
2614
2615     /*
2616      * GetProcess returns the process containing the assembly
2617      */
2618     COM_METHOD GetProcess(ICorDebugProcess ** ppProcess);
2619
2620     // Gets the AppDomain containing this assembly
2621     COM_METHOD GetAppDomain(ICorDebugAppDomain ** ppAppDomain);
2622
2623     /*
2624      * EnumerateModules enumerates all modules in the assembly
2625      */
2626     COM_METHOD EnumerateModules(ICorDebugModuleEnum ** ppModules);
2627
2628     /*
2629      * GetCodeBase returns the code base used to load the assembly
2630      */
2631     COM_METHOD GetCodeBase(ULONG32   cchName,
2632                            ULONG32 * pcchName,
2633                            __out_ecount_part_opt(cchName, *pcchName) WCHAR     szName[]);
2634
2635     // returns the filename of the assembly, or "<unknown>" for in-memory assemblies
2636     COM_METHOD GetName(ULONG32   cchName,
2637                        ULONG32 * pcchName,
2638                        __out_ecount_part_opt(cchName, *pcchName) WCHAR     szName[]);
2639
2640
2641     //-----------------------------------------------------------
2642     // ICorDebugAssembly2
2643     //-----------------------------------------------------------
2644
2645     /*
2646      * IsFullyTrusted returns a flag indicating whether the security system 
2647      * has granted the assembly full trust.
2648      */
2649     COM_METHOD IsFullyTrusted(BOOL * pbFullyTrusted);
2650
2651     //-----------------------------------------------------------
2652     // internal accessors
2653     //-----------------------------------------------------------
2654
2655 #ifdef _DEBUG
2656     void DbgAssertAssemblyDeleted();
2657
2658     static void DbgAssertAssemblyDeletedCallback(VMPTR_DomainAssembly vmDomainAssembly, void * pUserData);
2659 #endif // _DEBUG
2660
2661     CordbAppDomain * GetAppDomain()     { return m_pAppDomain; }
2662
2663     VMPTR_DomainAssembly    GetDomainAssemblyPtr() { return m_vmDomainAssembly; }
2664 private:
2665     VMPTR_Assembly          m_vmAssembly;
2666     VMPTR_DomainAssembly    m_vmDomainAssembly;
2667     CordbAppDomain *        m_pAppDomain;
2668
2669     StringCopyHolder        m_strAssemblyFileName;
2670     Optional<BOOL>          m_foptIsFullTrust;
2671 };
2672
2673
2674 //-----------------------------------------------------------------------------
2675 // Describe what to do w/ a win32 debug event
2676 //-----------------------------------------------------------------------------
2677 class Reaction
2678 {
2679 public:
2680     enum Type
2681     {
2682         // Inband events: Dispatch to Cordbg
2683         // safe for stopping the shell and communicating with the runtime
2684         cInband,
2685
2686         // workaround. Inband event, but NewEvent =false
2687         cInband_NotNewEvent,
2688
2689         // This is a debug event that corresponds with getting to the beginning
2690         // of a first chance hijack.
2691         cFirstChanceHijackStarted,
2692
2693         // This is the debug event that corresponds with getting to the end of
2694         // a hijack. To continue we need to restore an unhijacked context
2695         cInbandHijackComplete,
2696
2697         // This is a debug event which corresponds to re-hiting a previous
2698         // IB event after returning from the hijack. Now we have already dispatched it
2699         // so we know how the user wants it to be continued
2700         // Continue immediately with the previously determined 
2701         cInbandExceptionRetrigger,
2702
2703         // This debug event is a breakpoint in unmanaged code that we placed. It will need
2704         // the M2UHandoffHijack to run the in process breakpoint handling code.
2705         cBreakpointRequiringHijack,
2706
2707         // Oob events: Dispatch to Cordbg
2708         // Not safe stopping events. They must be continued immediately.
2709         cOOB,
2710
2711         // CLR internal exception, Continue(not_handled), don't dispatch
2712         // The CLR expects this exception and will deal with it properly.
2713         cCLR,
2714
2715         // Don't dispatch. Continue(DBG_CONTINUE).
2716         // Common for flare.
2717         cIgnore
2718     };
2719
2720     Type GetType() const { return m_type; };
2721
2722 #ifdef _DEBUG
2723     const char * GetReactionName()
2724     {
2725         switch(m_type)
2726         {
2727             case cInband: return "cInband";
2728             case cInband_NotNewEvent: return "cInband_NotNewEvent";
2729             case cInbandHijackComplete: return "cInbandHijackComplete";
2730             case cInbandExceptionRetrigger: return "cInbandExceptionRetrigger";
2731             case cBreakpointRequiringHijack: return "cBreakpointRequiringHijack";
2732             case cOOB: return "cOOB";
2733             case cCLR: return "cCLR";
2734             case cIgnore: return "cIgnore";
2735             default: return "<unknown>";
2736         }
2737     }
2738     int GetLine()
2739     {
2740         return m_line;
2741     }
2742 #endif
2743
2744     Reaction(Type t, int line) : m_type(t) {
2745 #ifdef _DEBUG
2746         m_line = line;
2747
2748         LOG((LF_CORDB, LL_EVERYTHING, "Reaction:%s (determined on line: %d)\n", GetReactionName(), line));
2749 #endif
2750     };
2751
2752     void operator=(const Reaction & other)
2753     {
2754         m_type = other.m_type;
2755 #ifdef _DEBUG
2756         m_line = other.m_line;
2757 #endif
2758     }
2759
2760 protected:
2761     Type m_type;
2762
2763 #ifdef _DEBUG
2764     // Under a debug build, track the line # for where this came from.
2765     int m_line;
2766 #endif
2767 };
2768
2769 // Macro for creating a Reaction.
2770 #define REACTION(type) Reaction(Reaction::type, __LINE__)
2771
2772 // Different forms of Unmanaged Continue
2773 enum EUMContinueType
2774 {
2775     cOobUMContinue,
2776     cInternalUMContinue,
2777     cRealUMContinue
2778 };
2779
2780 /* ------------------------------------------------------------------------- *
2781  * Process class
2782  * ------------------------------------------------------------------------- */
2783
2784
2785 #ifdef _DEBUG
2786 // On debug, we can afford a larger native event queue..
2787 const int DEBUG_EVENTQUEUE_SIZE = 30;
2788 #else
2789 const int DEBUG_EVENTQUEUE_SIZE = 10;
2790 #endif
2791
2792 void DeleteIPCEventHelper(DebuggerIPCEvent *pDel);
2793
2794
2795 // Private interface on CordbProcess that ShimProcess needs to emulate V2 functionality.
2796 // The fact that we need private hooks means that V3 is not sufficiently finished to allow building
2797 // a V2 debugger. This interface should shrink over time (and eventually go away) as the functionality gets exposed
2798 // publicly. 
2799 // CordbProcess calls back into ShimProcess too, so the public surface of code:ShimProcess plus
2800 // the spots in CordbProcess that call them are additional surface area that may need to addressed
2801 // to make the shim public.
2802 class IProcessShimHooks
2803 {
2804 public:
2805     // Get the OS Process ID of the target.
2806     virtual DWORD GetPid() = 0;
2807
2808     // Request a synchronization for attach. 
2809     // This essentially just sends an AsyncBreak to the left-side. Once the target is
2810     // synchronized, the Shim can use inspection to send all the various fake-attach events. 
2811     // 
2812     // Once the shim has a way of requesting a synchronization from out-of-process for an
2813     // arbitrary running target that's not stopped at a managed debug event, we can
2814     // remove this.
2815     virtual void QueueManagedAttachIfNeeded() = 0;
2816
2817     // Hijack a thread at an unhandled exception to allow us to resume executing the target so
2818     // that the helper thread can run and service IPC requests. This is also needed to allow
2819     // func-eval at a 2nd-chance exception
2820     // 
2821     // This will require an architectural change to remove. Either:
2822     // - actions like func-eval / synchronization may call this directly themselves.
2823     // - the CLR's managed Unhandled-exception event is moved out of the native
2824     // unhandled-exception event, thus making native unhandled exceptions uninteresting to ICorDebug.
2825     // - everything is out-of-process, and so the CLR doesn't need to continue after an unhandled
2826     // native exception.
2827     virtual BOOL HijackThreadForUnhandledExceptionIfNeeded(DWORD dwThreadId) = 0;
2828
2829 #ifdef FEATURE_INTEROP_DEBUGGING
2830     // Private hook to do the bulk of the interop-debugging goo. This includes hijacking inband
2831     // events and queueing them so that the helper-thread can run.
2832     // 
2833     // We can remove this once we kill the helper-thread, or after enough functionality is
2834     // out-of-process that the debugger doesn't need the helper thread when stopped at an event. 
2835     virtual void HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEvent) = 0;
2836 #endif // FEATURE_INTEROP_DEBUGGING
2837
2838     // Get the modules in the order that they were loaded. This is needed to send the fake-attach events
2839     // for module load in the right order.
2840     // 
2841     // This can be removed once ICorDebug's enumerations are ordered.
2842     virtual void GetModulesInLoadOrder(
2843         ICorDebugAssembly * pAssembly, 
2844         RSExtSmartPtr<ICorDebugModule>* pModules,
2845         ULONG countModules) = 0;
2846     
2847     // Get the assemblies in the order that they were loaded. This is needed to send the fake-attach events
2848     // for assembly load in the right order.
2849     // 
2850     // This can be removed once ICorDebug's enumerations are ordered.
2851     virtual void GetAssembliesInLoadOrder(
2852         ICorDebugAppDomain * pAppDomain, 
2853         RSExtSmartPtr<ICorDebugAssembly>* pAssemblies,
2854         ULONG countAssemblies) = 0;
2855
2856     // Queue up fake connection events for attach.
2857     // ICorDebug doesn't expose any enumeration for connections, so the shim needs to call into a
2858     // private hook to enumerate them for attach.
2859     virtual void QueueFakeConnectionEvents() = 0;
2860
2861     // This finishes initializing the IPC channel between the LS + RS, which includes duplicating
2862     // some handles and events. 
2863     // 
2864     // This can be removed once the IPC channel is completely gone and all communication goes
2865     // soley through the data-target.
2866     virtual void FinishInitializeIPCChannel() = 0;
2867     
2868     // Called when stopped at a managed debug event to request a synchronization.
2869     // This can be replaced when we expose synchronization from ICorDebug.
2870     // The fact that the debuggee is at a managed debug event greatly simplifies the request here
2871     // (in contrast to QueueManagedAttachIfNeeded). It means that we can just flip a flag from
2872     // out-of-process, and when the debuggee thread resumes, it can check that flag and do the
2873     // synchronization from in-process.
2874     virtual void RequestSyncAtEvent()= 0;
2875     
2876     virtual bool IsThreadSuspendedOrHijacked(ICorDebugThread * pThread) = 0;
2877 };
2878
2879
2880 // entry for the array of connections in EnumerateConnectionsData
2881 struct EnumerateConnectionsEntry
2882 {
2883 public:
2884     StringCopyHolder m_pName;   // name of the connection
2885     DWORD            m_dwID;    // ID of the connection
2886 };
2887
2888 // data structure used in the callback for enumerating connections (code:CordbProcess::QueueFakeConnectionEvents)
2889 struct EnumerateConnectionsData
2890 {
2891 public:
2892     ~EnumerateConnectionsData()
2893     {
2894         if (m_pEntryArray != NULL)
2895         {
2896             delete [] m_pEntryArray;
2897             m_pEntryArray = NULL;
2898         }
2899     }
2900
2901     CordbProcess * m_pThis;                     // the "this" process
2902     EnumerateConnectionsEntry * m_pEntryArray;  // an array of connections to be filled in 
2903     UINT32         m_uIndex;                    // the next entry in the array to be filled
2904 };
2905
2906 // data structure used in the callback for asserting that an appdomain has been deleted
2907 // (code:CordbProcess::DbgAssertAppDomainDeleted)
2908 struct DbgAssertAppDomainDeletedData
2909 {
2910 public:
2911     CordbProcess *  m_pThis;
2912     VMPTR_AppDomain m_vmAppDomainDeleted;
2913 };
2914
2915 class CordbProcess : 
2916     public CordbBase, 
2917     public ICorDebugProcess, 
2918     public ICorDebugProcess2, 
2919     public ICorDebugProcess3, 
2920     public ICorDebugProcess4,
2921     public ICorDebugProcess5,
2922     public ICorDebugProcess7,
2923     public ICorDebugProcess8,
2924     public IDacDbiInterface::IAllocator,
2925     public IDacDbiInterface::IMetaDataLookup,
2926     public IProcessShimHooks
2927 #ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
2928     , public ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly
2929 #endif
2930 {
2931     // Ctor is private. Use OpenVirtualProcess instead. 
2932     CordbProcess(ULONG64 clrInstanceId, IUnknown * pDataTarget, HMODULE hDacModule,  Cordb * pCordb, DWORD dwProcessID, ShimProcess * pShim);
2933
2934 public:    
2935
2936     virtual ~CordbProcess();
2937     virtual void Neuter();
2938
2939     // Neuter left-side resources for all children
2940     void NeuterChildrenLeftSideResources();
2941
2942     // Neuter all of all children, but not the actual process object.
2943     void NeuterChildren();
2944
2945
2946     // The way to instantiate a new CordbProcess object.
2947     // @dbgtodo  managed pipeline - this is not fully active in all scenarios yet.
2948     static HRESULT OpenVirtualProcess(ULONG64 clrInstanceId,
2949                                       IUnknown * pDataTarget, 
2950                                       HMODULE hDacModule,
2951                                       Cordb * pCordb, 
2952                                       DWORD dwProcessID, 
2953                                       ShimProcess * pShim, 
2954                                       CordbProcess ** ppProcess);
2955
2956     // Helper function to determine whether this ICorDebug is compatibile with a debugger
2957     // designed for the specified major version
2958     static bool IsCompatibleWith(DWORD clrMajorVersion);
2959
2960     //-----------------------------------------------------------
2961     // IMetaDataLookup
2962     // -----------------------------------------------------------    
2963     IMDInternalImport * LookupMetaData(VMPTR_PEFile vmPEFile, bool &isILMetaDataForNGENImage);
2964
2965     // Helper functions for LookupMetaData implementation
2966     IMDInternalImport * LookupMetaDataFromDebugger(VMPTR_PEFile vmPEFile,
2967                                                    bool &isILMetaDataForNGENImage,
2968                                                    CordbModule * pModule);
2969
2970     IMDInternalImport * LookupMetaDataFromDebuggerForSingleFile(CordbModule * pModule,
2971                                                                 LPCWSTR pwszImagePath,
2972                                                                 DWORD dwTimeStamp,
2973                                                                 DWORD dwImageSize);
2974
2975
2976     //-----------------------------------------------------------
2977     // IDacDbiInterface::IAllocator 
2978     //-----------------------------------------------------------
2979
2980     void * Alloc(SIZE_T lenBytes);
2981     void Free(void * p);
2982
2983 #ifdef _DEBUG
2984     virtual const char * DbgGetName() { return "CordbProcess"; }
2985 #endif
2986
2987     //-----------------------------------------------------------
2988     // IUnknown
2989     //-----------------------------------------------------------
2990
2991     ULONG STDMETHODCALLTYPE AddRef()
2992     {
2993         return BaseAddRefEnforceExternal();
2994     }
2995     ULONG STDMETHODCALLTYPE Release()
2996     {
2997         return BaseReleaseEnforceExternal();
2998     }
2999     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
3000
3001     //-----------------------------------------------------------
3002     // ICorDebugController
3003     //-----------------------------------------------------------
3004
3005     COM_METHOD Stop(DWORD dwTimeout);
3006     COM_METHOD Deprecated_Continue();
3007     COM_METHOD IsRunning(BOOL *pbRunning);
3008     COM_METHOD HasQueuedCallbacks(ICorDebugThread *pThread, BOOL *pbQueued);
3009     COM_METHOD EnumerateThreads(ICorDebugThreadEnum **ppThreads);
3010     COM_METHOD SetAllThreadsDebugState(CorDebugThreadState state,
3011                                        ICorDebugThread *pExceptThisThread);
3012     COM_METHOD Detach();
3013     COM_METHOD Terminate(unsigned int exitCode);
3014
3015     COM_METHOD CanCommitChanges(
3016         ULONG cSnapshots,
3017         ICorDebugEditAndContinueSnapshot *pSnapshots[],
3018         ICorDebugErrorInfoEnum **pError);
3019
3020     COM_METHOD CommitChanges(
3021         ULONG cSnapshots,
3022         ICorDebugEditAndContinueSnapshot *pSnapshots[],
3023         ICorDebugErrorInfoEnum **pError);
3024
3025     COM_METHOD Continue(BOOL fIsOutOfBand);
3026     COM_METHOD ThreadForFiberCookie(DWORD fiberCookie,
3027                                     ICorDebugThread **ppThread);
3028     COM_METHOD GetHelperThreadID(DWORD *pThreadID);
3029
3030     //-----------------------------------------------------------
3031     // ICorDebugProcess
3032     //-----------------------------------------------------------
3033
3034     COM_METHOD GetID(DWORD *pdwProcessId);
3035     COM_METHOD GetHandle(HANDLE *phProcessHandle);
3036     COM_METHOD EnableSynchronization(BOOL bEnableSynchronization);
3037     COM_METHOD GetThread(DWORD dwThreadId, ICorDebugThread **ppThread);
3038     COM_METHOD EnumerateBreakpoints(ICorDebugBreakpointEnum **ppBreakpoints);
3039     COM_METHOD EnumerateSteppers(ICorDebugStepperEnum **ppSteppers);
3040     COM_METHOD EnumerateObjects(ICorDebugObjectEnum **ppObjects);
3041     COM_METHOD IsTransitionStub(CORDB_ADDRESS address, BOOL *pbTransitionStub);
3042     COM_METHOD EnumerateModules(ICorDebugModuleEnum **ppModules);
3043     COM_METHOD GetModuleFromMetaDataInterface(IUnknown *pIMetaData,
3044                                               ICorDebugModule **ppModule);
3045     COM_METHOD SetStopState(DWORD threadID, CorDebugThreadState state);
3046     COM_METHOD IsOSSuspended(DWORD threadID, BOOL *pbSuspended);
3047     COM_METHOD GetThreadContext(DWORD threadID, ULONG32 contextSize,
3048                                 BYTE context[]);
3049     COM_METHOD SetThreadContext(DWORD threadID, ULONG32 contextSize,
3050                                 BYTE context[]);
3051     COM_METHOD ReadMemory(CORDB_ADDRESS address, DWORD size, BYTE buffer[],
3052                           SIZE_T *read);
3053     COM_METHOD WriteMemory(CORDB_ADDRESS address, DWORD size, BYTE buffer[],
3054                            SIZE_T *written);
3055
3056     COM_METHOD ClearCurrentException(DWORD threadID);
3057
3058     /*
3059      * EnableLogMessages enables/disables sending of log messages to the
3060      * debugger for logging.
3061      */
3062     COM_METHOD EnableLogMessages(BOOL fOnOff);
3063
3064     /*
3065      * ModifyLogSwitch modifies the specified switch's severity level.
3066      */
3067     COM_METHOD ModifyLogSwitch(__in_z WCHAR *pLogSwitchName, LONG lLevel);
3068
3069     COM_METHOD EnumerateAppDomains(ICorDebugAppDomainEnum **ppAppDomains);
3070     COM_METHOD GetObject(ICorDebugValue **ppObject);
3071
3072     //-----------------------------------------------------------
3073     // ICorDebugProcess2
3074     //-----------------------------------------------------------
3075
3076     COM_METHOD GetThreadForTaskID(TASKID taskId, ICorDebugThread2 ** ppThread);
3077     COM_METHOD GetVersion(COR_VERSION* pInfo);
3078
3079     COM_METHOD SetUnmanagedBreakpoint(CORDB_ADDRESS address, ULONG32 bufsize, BYTE buffer[], ULONG32 * bufLen);
3080     COM_METHOD ClearUnmanagedBreakpoint(CORDB_ADDRESS address);
3081     COM_METHOD GetCodeAtAddress(CORDB_ADDRESS address, ICorDebugCode ** pCode, ULONG32 * offset);
3082
3083     COM_METHOD SetDesiredNGENCompilerFlags(DWORD pdwFlags);
3084     COM_METHOD GetDesiredNGENCompilerFlags(DWORD *pdwFlags );
3085
3086     COM_METHOD GetReferenceValueFromGCHandle(UINT_PTR handle, ICorDebugReferenceValue **pOutValue);
3087
3088     //-----------------------------------------------------------
3089     // ICorDebugProcess3
3090     //-----------------------------------------------------------
3091
3092     // enables or disables CustomNotifications of a given type 
3093     COM_METHOD SetEnableCustomNotification(ICorDebugClass * pClass, BOOL fEnable);
3094
3095     //-----------------------------------------------------------
3096     // ICorDebugProcess4
3097     //-----------------------------------------------------------
3098     COM_METHOD Filter(        
3099         const BYTE pRecord[],
3100         DWORD countBytes,
3101         CorDebugRecordFormat format,
3102         DWORD dwFlags, 
3103         DWORD dwThreadId, 
3104         ICorDebugManagedCallback *pCallback,
3105         DWORD * pContinueStatus);
3106
3107     COM_METHOD ProcessStateChanged(CorDebugStateChange eChange);
3108
3109     //-----------------------------------------------------------
3110     // ICorDebugProcess5
3111     //-----------------------------------------------------------
3112     COM_METHOD GetGCHeapInformation(COR_HEAPINFO *pHeapInfo);
3113     COM_METHOD EnumerateHeap(ICorDebugHeapEnum **ppObjects);
3114     COM_METHOD EnumerateHeapRegions(ICorDebugHeapSegmentEnum **ppRegions);
3115     COM_METHOD GetObject(CORDB_ADDRESS addr, ICorDebugObjectValue **pObject);
3116     COM_METHOD EnableNGENPolicy(CorDebugNGENPolicy ePolicy);
3117     COM_METHOD EnumerateGCReferences(BOOL enumerateWeakReferences, ICorDebugGCReferenceEnum **ppEnum);
3118     COM_METHOD EnumerateHandles(CorGCReferenceType types, ICorDebugGCReferenceEnum **ppEnum);
3119     COM_METHOD GetTypeID(CORDB_ADDRESS obj, COR_TYPEID *pId);
3120     COM_METHOD GetTypeForTypeID(COR_TYPEID id, ICorDebugType **ppType);
3121     COM_METHOD GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLayout);
3122     COM_METHOD GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT *pLayout);
3123     COM_METHOD GetTypeFields(COR_TYPEID id, ULONG32 celt, COR_FIELD fields[], ULONG32 *pceltNeeded);
3124
3125     //-----------------------------------------------------------
3126     // ICorDebugProcess7
3127     //-----------------------------------------------------------
3128     COM_METHOD SetWriteableMetadataUpdateMode(WriteableMetadataUpdateMode flags);
3129
3130     //-----------------------------------------------------------
3131     // ICorDebugProcess8
3132     //-----------------------------------------------------------
3133     COM_METHOD EnableExceptionCallbacksOutsideOfMyCode(BOOL enableExceptionsOutsideOfJMC);
3134
3135 #ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
3136     // ---------------------------------------------------------------
3137     // ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly
3138     // ---------------------------------------------------------------
3139
3140     COM_METHOD InvokePauseCallback();
3141     COM_METHOD InvokeResumeCallback();
3142
3143 #endif
3144
3145     //-----------------------------------------------------------
3146     // Methods not exposed via a COM interface.
3147     //-----------------------------------------------------------
3148
3149     HRESULT ContinueInternal(BOOL fIsOutOfBand);
3150     HRESULT StopInternal(DWORD dwTimeout, VMPTR_AppDomain pAppDomainToken);
3151
3152     // Sets an unmanaged breakpoint at the target address
3153     HRESULT SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufsize, BYTE buffer[], ULONG32 * bufLen);
3154
3155     // Allocate a buffer within the target and return the range. Throws on error.
3156     TargetBuffer GetRemoteBuffer(ULONG cbBuffer); // throws
3157
3158     // Same as above except also copy-in the contents of a RS buffer using WriteProcessMemory
3159     HRESULT GetAndWriteRemoteBuffer(CordbAppDomain *pDomain, unsigned int bufferSize, const void *bufferFrom, void **ppBuffer);
3160
3161     /*
3162      * This will release a previously allocated left side buffer.
3163      * Often they are deallocated by the LS itself.
3164      */
3165     HRESULT ReleaseRemoteBuffer(void **ppBuffer);
3166
3167
3168     void TargetConsistencyCheck(bool fExpression);
3169
3170     // Activate interop-debugging, after the process has initially been Init()
3171     void EnableInteropDebugging();
3172
3173     HRESULT Init();
3174     void DeleteQueuedEvents();
3175     void CleanupHalfBakedLeftSide();
3176     void Terminating(BOOL fDetach);
3177
3178     CordbThread * TryLookupThread(VMPTR_Thread vmThread);
3179     CordbThread * TryLookupOrCreateThreadByVolatileOSId(DWORD dwThreadId);
3180     CordbThread * TryLookupThreadByVolatileOSId(DWORD dwThreadId);
3181     CordbThread * LookupOrCreateThread(VMPTR_Thread vmThread);
3182
3183     void QueueManagedAttachIfNeeded();
3184     void QueueManagedAttachIfNeededWorker();
3185     HRESULT QueueManagedAttach();
3186
3187     void DetachShim();
3188
3189     // Flush for when the process is running.
3190     void FlushProcessRunning();
3191
3192     // Flush all state.
3193     void FlushAll();
3194
3195     BOOL HijackThreadForUnhandledExceptionIfNeeded(DWORD dwThreadId);
3196
3197     // Filter a CLR notification (subset of exceptions).
3198     void FilterClrNotification(
3199         DebuggerIPCEvent * pManagedEvent, 
3200         RSLockHolder * pLockHolder,
3201         ICorDebugManagedCallback * pCallback);
3202
3203     // Wrapper to invoke IClrDataTarget4::ContinueStatusChanged
3204     void ContinueStatusChanged(DWORD dwThreadId, CORDB_CONTINUE_STATUS dwContinueStatus);
3205
3206
3207     // Request a synchronization to occur after a debug event is dispatched.
3208     void RequestSyncAtEvent();    
3209
3210     //
3211     // Basic managed event plumbing
3212     //
3213
3214     // This is called on the first IPC event from the debuggee. It initializes state. 
3215     void FinishInitializeIPCChannel();
3216     void FinishInitializeIPCChannelWorker();
3217
3218     // This is called on each IPC event from the debuggee.
3219     void HandleRCEvent(DebuggerIPCEvent * pManagedEvent, RSLockHolder * pLockHolder, ICorDebugManagedCallback * pCallback);
3220
3221     // Queue the RC event.
3222     void QueueRCEvent(DebuggerIPCEvent * pManagedEvent);
3223
3224     // This marshals a managed debug event from the 
3225     void MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent);
3226
3227     // This copies a managed debug event from the IPC block and to pManagedEvent.
3228     // The event still needs to be marshalled.
3229     void CopyRCEventFromIPCBlock(DebuggerIPCEvent * pManagedEvent);
3230
3231     // This copies a managed debug event out of the Native-Debug event envelope.
3232     // The event still needs to be marshalled.
3233     bool CopyManagedEventFromTarget(const EXCEPTION_RECORD * pRecord, DebuggerIPCEvent * pLocalManagedEvent);
3234
3235     // Helper for Filter() to verify parameters and return a type-safe exception record.
3236     const EXCEPTION_RECORD * ValidateExceptionRecord(
3237         const BYTE pRawRecord[],
3238         DWORD countBytes,
3239         CorDebugRecordFormat format);
3240
3241     // Helper to read a structure from the target.
3242     template<typename T>
3243     HRESULT SafeReadStruct(CORDB_ADDRESS pRemotePtr, T* pLocalBuffer);
3244
3245     // Helper to write a structure into the target.
3246     template<typename T> 
3247     HRESULT SafeWriteStruct(CORDB_ADDRESS pRemotePtr, const T* pLocalBuffer);
3248
3249     // Reads a buffer from the target
3250     HRESULT SafeReadBuffer(TargetBuffer tb, BYTE * pLocalBuffer, BOOL throwOnError = TRUE);
3251
3252     // Writes a buffer to the target
3253     void SafeWriteBuffer(TargetBuffer tb, const BYTE * pLocalBuffer);
3254
3255 #if defined(FEATURE_INTEROP_DEBUGGING)
3256     void DuplicateHandleToLocalProcess(HANDLE * pLocalHandle, RemoteHANDLE * pRemoteHandle);
3257 #endif // FEATURE_INTEROP_DEBUGGING
3258
3259     bool IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThread);
3260
3261     // Helper to get PID internally.
3262     DWORD GetPid();
3263
3264     HRESULT GetRuntimeOffsets();
3265         
3266     // Are we blocked waiting fo ran OOB event to be continue?
3267     bool IsWaitingForOOBEvent()
3268     {
3269 #ifdef FEATURE_INTEROP_DEBUGGING
3270         return m_outOfBandEventQueue != NULL;
3271 #else
3272         // If no interop, then we're never waiting for an OOB event.
3273         return false;
3274 #endif
3275     }
3276
3277     //
3278     // Shim  callbacks to simulate fake attach events. 
3279     // 
3280
3281
3282     // Callback for Shim to get the assemblies in load order 
3283     void GetAssembliesInLoadOrder(
3284         ICorDebugAppDomain * pAppDomain, 
3285         RSExtSmartPtr<ICorDebugAssembly>* pAssemblies,
3286         ULONG countAssemblies);
3287
3288     // Callback for Shim to get the modules in load order 
3289     void GetModulesInLoadOrder(
3290         ICorDebugAssembly * pAssembly, 
3291         RSExtSmartPtr<ICorDebugModule>* pModules,
3292         ULONG countModules);
3293
3294     // Functions to queue fake Connection events on attach.
3295     static void CountConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData);
3296     static void EnumerateConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData);
3297     void QueueFakeConnectionEvents();
3298
3299
3300
3301     void DispatchRCEvent();
3302
3303     // Dispatch a single event via the callbacks.
3304     void RawDispatchEvent(
3305         DebuggerIPCEvent *          pEvent, 
3306         RSLockHolder *              pLockHolder,
3307         ICorDebugManagedCallback *  pCallback1, 
3308         ICorDebugManagedCallback2 * pCallback2,
3309         ICorDebugManagedCallback3 * pCallback3);
3310
3311     void MarkAllThreadsDirty();
3312
3313     bool CheckIfLSExited();
3314
3315     void Lock()
3316     {
3317         // Lock Hierarchy - shouldn't have List lock when taking/release the process lock.
3318
3319         m_processMutex.Lock();
3320         LOG((LF_CORDB, LL_EVERYTHING, "P::Lock enter, this=0x%p\n", this));
3321     }
3322
3323     void Unlock()
3324     {
3325         // Lock Hierarchy - shouldn't have List lock when taking/releasing the process lock.
3326
3327         LOG((LF_CORDB, LL_EVERYTHING, "P::Lock leave, this=0x%p\n", this));
3328         m_processMutex.Unlock();
3329     }
3330
3331 #ifdef _DEBUG
3332     bool ThreadHoldsProcessLock()
3333     {
3334         return m_processMutex.HasLock();
3335     }
3336 #endif
3337
3338     // Expose the process lock.
3339     // This is the main lock in V3.
3340     RSLock * GetProcessLock()
3341     {
3342         return &m_processMutex;
3343     }
3344
3345
3346     // @dbgtodo  synchronization - the SG lock goes away in V3.
3347     // Expose the stop-go lock b/c varios Cordb objects in our process tree may need to take it.
3348     RSLock * GetStopGoLock()
3349     {
3350         return &m_StopGoLock;
3351     }
3352
3353
3354     void UnrecoverableError(HRESULT errorHR,
3355                             unsigned int errorCode,
3356                             const char *errorFile,
3357                             unsigned int errorLine);
3358     HRESULT CheckForUnrecoverableError();
3359     void VerifyControlBlock();
3360
3361     // The implementation of EnumerateThreads without the public API error checks
3362     VOID InternalEnumerateThreads(RSInitHolder<CordbHashTableEnum> * ppThreads);
3363
3364     //-----------------------------------------------------------
3365     // Convenience routines
3366     //-----------------------------------------------------------
3367
3368     // Is it safe to send events to the LS?
3369     bool IsSafeToSendEvents() { return !m_unrecoverableError && !m_terminated && !m_detached; }
3370
3371     bool IsWin32EventThread();
3372
3373     void HandleSyncCompleteRecieved();
3374
3375     // Send a truly asynchronous IPC event.
3376     void SendAsyncIPCEvent(DebuggerIPCEventType t);
3377
3378     HRESULT SendIPCEvent(DebuggerIPCEvent *event, SIZE_T eventSize)
3379     {
3380         // @dbgtodo - eventually remove this when all IPC events are gone.
3381         // In V3 paths, we can't send IPC events.
3382         if (GetShim() == NULL)
3383         {
3384             STRESS_LOG1(LF_CORDB, LL_INFO1000, "!! Can't send IPC event in V3. %s", IPCENames::GetName(event->type));
3385             return E_NOTIMPL;
3386         }
3387         _ASSERTE(m_cordb != NULL);
3388         return (m_cordb->SendIPCEvent(this, event, eventSize));
3389     }
3390
3391     void InitAsyncIPCEvent(DebuggerIPCEvent *ipce,
3392                       DebuggerIPCEventType type,
3393                       VMPTR_AppDomain vmAppDomain)
3394     {
3395         // Async events only allowed for the following:
3396         _ASSERTE(type == DB_IPCE_ATTACHING);
3397
3398         InitIPCEvent(ipce, type, false, vmAppDomain);
3399         ipce->asyncSend = true;
3400     }
3401
3402     void InitIPCEvent(DebuggerIPCEvent *ipce,
3403                       DebuggerIPCEventType type,
3404                       bool twoWay,
3405                       VMPTR_AppDomain vmAppDomain
3406                       )
3407     {
3408         // zero out the event in case we try and use any uninitialized fields
3409         memset( ipce, 0, sizeof(DebuggerIPCEvent) );
3410         
3411         _ASSERTE((!vmAppDomain.IsNull()) ||
3412                  type == DB_IPCE_GET_GCHANDLE_INFO ||
3413                  type == DB_IPCE_ENABLE_LOG_MESSAGES ||
3414                  type == DB_IPCE_MODIFY_LOGSWITCH ||
3415                  type == DB_IPCE_ASYNC_BREAK ||
3416                  type == DB_IPCE_CONTINUE ||
3417                  type == DB_IPCE_GET_BUFFER ||
3418                  type == DB_IPCE_RELEASE_BUFFER ||
3419                  type == DB_IPCE_IS_TRANSITION_STUB ||
3420                  type == DB_IPCE_ATTACHING ||
3421                  type == DB_IPCE_APPLY_CHANGES ||
3422                  type == DB_IPCE_CONTROL_C_EVENT_RESULT ||
3423                  type == DB_IPCE_SET_REFERENCE ||
3424                  type == DB_IPCE_SET_ALL_DEBUG_STATE ||
3425                  type == DB_IPCE_GET_THREAD_FOR_TASKID ||
3426                  type == DB_IPCE_DETACH_FROM_PROCESS ||
3427                  type == DB_IPCE_INTERCEPT_EXCEPTION ||
3428                  type == DB_IPCE_GET_NGEN_COMPILER_FLAGS ||
3429                  type == DB_IPCE_SET_NGEN_COMPILER_FLAGS || 
3430                  type == DB_IPCE_SET_VALUE_CLASS);
3431
3432         ipce->type = type;
3433         ipce->hr = S_OK;
3434         ipce->processId = 0;
3435         ipce->vmAppDomain = vmAppDomain;
3436         ipce->vmThread = VMPTR_Thread::NullPtr();
3437         ipce->replyRequired = twoWay;
3438         ipce->asyncSend = false;
3439         ipce->next = NULL;
3440     }
3441
3442     // Looks up a previously constructed CordbClass instance without creating. May return NULL if the 
3443     // CordbClass instance doesn't exist.
3444     CordbClass * LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_DomainFile vmDomainFile, mdTypeDef classToken);
3445
3446     CordbModule * LookupOrCreateModule(VMPTR_DomainFile vmDomainFile);
3447
3448 #ifdef FEATURE_INTEROP_DEBUGGING
3449     CordbUnmanagedThread *GetUnmanagedThread(DWORD dwThreadId)
3450     {
3451         _ASSERTE(ThreadHoldsProcessLock());
3452         return m_unmanagedThreads.GetBase(dwThreadId);
3453     }
3454 #endif // FEATURE_INTEROP_DEBUGGING
3455
3456     /*
3457      * This will cleanup the patch table, releasing memory,etc.
3458      */
3459     void ClearPatchTable();
3460
3461     /*
3462      * This will grab the patch table from the left side & go through
3463      * it to gather info needed for faster access.  If address,size,buffer
3464      * are passed in, while going through the table we'll undo patches
3465      * in buffer at the same time
3466      */
3467     HRESULT RefreshPatchTable(CORDB_ADDRESS address = NULL, SIZE_T size = NULL, BYTE buffer[] = NULL);
3468
3469     // Find if a patch exists at a given address.
3470     HRESULT FindPatchByAddress(CORDB_ADDRESS address, bool *patchFound, bool *patchIsUnmanaged);
3471
3472     enum AB_MODE
3473     {
3474         AB_READ,
3475         AB_WRITE
3476     };
3477
3478     /*
3479      * Once we've called RefreshPatchTable to get the patch table,
3480      * this routine will iterate through the patches & either apply
3481      * or unapply the patches to buffer. AB_READ => Replaces patches
3482      * in buffer with the original opcode, AB_WRTE => replace opcode
3483      * with breakpoint instruction, caller is responsible for
3484      * updating the patchtable back to the left side.
3485      *
3486      * <TODO>@todo Perf Instead of a copy, undo the changes
3487      * Since the 'buffer' arg is an [in] param, we're not supposed to
3488      * change it.  If we do, we'll allocate & copy it to bufferCopy
3489      * (we'll also set *pbUpdatePatchTable to true), otherwise we
3490      * don't manipuldate bufferCopy (so passing a NULL in for
3491      * reading is fine).</TODO>
3492      */
3493     HRESULT AdjustBuffer(CORDB_ADDRESS address,
3494                          SIZE_T size,
3495                          BYTE buffer[],
3496                          BYTE **bufferCopy,
3497                          AB_MODE mode,
3498                          BOOL *pbUpdatePatchTable = NULL);
3499
3500     /*
3501      * AdjustBuffer, above, doesn't actually update the local patch table
3502      * if asked to do a write.  It stores the changes alongside the table,
3503      * and this will cause the changes to be written to the table (for
3504      * a range of left-side addresses
3505      */
3506     void CommitBufferAdjustments(CORDB_ADDRESS start,
3507                                  CORDB_ADDRESS end);
3508
3509     /*
3510      * Clear the stored changes, or they'll sit there until we
3511      * accidentally commit them
3512      */
3513     void ClearBufferAdjustments();
3514
3515
3516
3517
3518     //-----------------------------------------------------------
3519     // Accessors for key synchronization fields.
3520     //-----------------------------------------------------------
3521
3522     // If CAD is NULL, returns true if all appdomains (ie, the entire process)
3523     // is synchronized.  Otherwise, returns true if the specified appdomain is
3524     // synch'd.
3525     bool GetSynchronized();
3526     void SetSynchronized(bool fSynch);
3527
3528     void IncStopCount();
3529     void DecStopCount();
3530
3531     // Gets the exact stop count. You need the Proecss lock for this.
3532     int GetStopCount();
3533
3534     // Just gets whether we're stopped or not (m_stopped > 0).
3535     // You only need the StopGo lock for this.
3536     // This is biases towards returning false.
3537     bool IsStopped();
3538
3539     bool GetSyncCompleteRecv();
3540     void SetSyncCompleteRecv(bool fSyncRecv);
3541
3542
3543     // Cordbg may not always continue during a callback; but we really shouldn't do meaningful
3544     // work after a callback has returned yet before they've called continue. Thus we may need
3545     // to remember some state at the time of dispatch so that we do stuff at continue.
3546     // Only example here is neutering... we'd like to Neuter an object X after the ExitX callback,
3547     // but we can't neuter it until Continue. So remember X when we dispatch, and neuter this at continue.
3548     // Use a smart ptr to keep it alive until we neuter it.
3549
3550     // Add objects to various neuter lists.
3551     // NeuterOnContinue is for all objects that can be neutered once we continue.
3552     // NeuterOnExit is for all objects that can survive continues (but are neutered on process shutdown).
3553     // If an object's external ref count goes to 0, it gets promoted to the NeuterOnContinue list.
3554     void AddToNeuterOnExitList(CordbBase *pObject);
3555     void AddToNeuterOnContinueList(CordbBase *pObject);
3556
3557     NeuterList * GetContinueNeuterList() { return &m_ContinueNeuterList; }
3558     NeuterList * GetExitNeuterList() { return &m_ExitNeuterList; }
3559
3560     void AddToLeftSideResourceCleanupList(CordbBase * pObject); 
3561
3562     // Routines to read and write thread context records between the processes safely.
3563     HRESULT SafeReadThreadContext(LSPTR_CONTEXT pRemoteContext, DT_CONTEXT * pCtx);
3564     HRESULT SafeWriteThreadContext(LSPTR_CONTEXT pRemoteContext, const DT_CONTEXT * pCtx);
3565
3566 #ifdef FEATURE_INTEROP_DEBUGGING
3567     // Record a win32 event for debugging purposes.
3568     void DebugRecordWin32Event(const DEBUG_EVENT * pEvent, CordbUnmanagedThread * pUThread);
3569 #endif // FEATURE_INTEROP_DEBUGGING
3570
3571     //-----------------------------------------------------------
3572     // Interop Helpers
3573     //-----------------------------------------------------------
3574
3575     // Get the DAC interface.
3576     IDacDbiInterface * GetDAC();
3577
3578     // Get the data-target, which provides access to the debuggee.
3579     ICorDebugDataTarget * GetDataTarget();
3580
3581     BOOL IsDacInitialized();
3582     
3583     void ForceDacFlush();
3584
3585
3586 #ifdef FEATURE_INTEROP_DEBUGGING
3587     // Deal with native debug events for the interop-debugging scenario.
3588     void HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEvent);
3589
3590     void ResumeHijackedThreads();
3591
3592     //@todo - We should try to make these all private
3593     CordbUnmanagedThread *HandleUnmanagedCreateThread(DWORD dwThreadId, HANDLE hThread, void *lpThreadLocalBase);
3594
3595     HRESULT ContinueOOB();
3596     void QueueUnmanagedEvent(CordbUnmanagedThread *pUThread, const DEBUG_EVENT *pEvent);
3597     void DequeueUnmanagedEvent(CordbUnmanagedThread *pUThread);
3598     void QueueOOBUnmanagedEvent(CordbUnmanagedThread *pUThread, const DEBUG_EVENT *pEvent);
3599     void DequeueOOBUnmanagedEvent(CordbUnmanagedThread *pUThread);
3600     void DispatchUnmanagedInBandEvent();
3601     void DispatchUnmanagedOOBEvent();
3602     bool ExceptionIsFlare(DWORD exceptionCode, const void *exceptionAddress);
3603
3604     bool IsSpecialStackOverflowCase(CordbUnmanagedThread *pUThread, const DEBUG_EVENT *pEvent);
3605
3606     HRESULT SuspendUnmanagedThreads();
3607     HRESULT ResumeUnmanagedThreads();
3608
3609     HRESULT HijackIBEvent(CordbUnmanagedEvent * pUnmanagedEvent);
3610             
3611     BOOL HasUndispatchedNativeEvents();
3612     BOOL HasUserUncontinuedNativeEvents();
3613 #endif // FEATURE_INTEROP_DEBUGGING
3614
3615     HRESULT StartSyncFromWin32Stop(BOOL * pfAsyncBreakSent);
3616
3617
3618     // For interop attach, we first do native, and then once Cordbg continues from
3619     // the loader-bp, we kick off the managed attach. This field remembers that
3620     // whether we need the managed attach.
3621     // @dbgtodo  managed pipeline - hoist to shim.
3622     bool m_fDoDelayedManagedAttached;
3623
3624
3625
3626     // Table of CordbEval objects that we've sent over to the LS.
3627     // This is synced via the process lock.
3628     RsPtrTable<CordbEval> m_EvalTable;
3629
3630     void PrepopulateThreadsOrThrow();
3631
3632     // Lookup or create an appdomain.
3633     CordbAppDomain * LookupOrCreateAppDomain(VMPTR_AppDomain vmAppDomain);
3634     
3635     // Get the shared app domain.
3636     CordbAppDomain * GetSharedAppDomain();
3637
3638     // Get metadata dispenser.
3639     IMetaDataDispenserEx * GetDispenser();
3640
3641     // Sets a bitfield reflecting the managed debugging state at the time of
3642     // the jit attach.
3643     HRESULT GetAttachStateFlags(CLR_DEBUGGING_PROCESS_FLAGS *pFlags);
3644
3645     HRESULT GetTypeForObject(CORDB_ADDRESS obj, CordbType **ppType, CordbAppDomain **pAppDomain = NULL);
3646
3647     WriteableMetadataUpdateMode GetWriteableMetadataUpdateMode() { return m_writableMetadataUpdateMode; }
3648 private:
3649
3650 #ifdef _DEBUG
3651     // Assert that vmAppDomainDeleted doesn't show up in dac enumerations
3652     void DbgAssertAppDomainDeleted(VMPTR_AppDomain vmAppDomainDeleted);
3653
3654     // Callback helper for DbgAssertAppDomainDeleted.
3655     static void DbgAssertAppDomainDeletedCallback(VMPTR_AppDomain vmAppDomain, void * pUserData);
3656 #endif // _DEBUG
3657
3658     static void ThreadEnumerationCallback(VMPTR_Thread vmThread, void * pUserData);
3659
3660
3661     // Callback for AppDomain enumeration
3662     static void AppDomainEnumerationCallback(VMPTR_AppDomain vmAppDomain, void * pUserData);
3663
3664     // Helper to create a new CordbAppDomain around the vmptr and cache it
3665     CordbAppDomain * CacheAppDomain(VMPTR_AppDomain vmAppDomain);
3666
3667     // Helper to traverse Appdomains in target and build up our cache.
3668     void PrepopulateAppDomainsOrThrow();
3669
3670     
3671     void ProcessFirstLogMessage (DebuggerIPCEvent *event);
3672     void ProcessContinuedLogMessage (DebuggerIPCEvent *event);
3673
3674     void CloseIPCHandles();
3675     void UpdateThreadsForAdUnload( CordbAppDomain* pAppDomain );
3676
3677 #ifdef FEATURE_INTEROP_DEBUGGING
3678     // Each win32 debug event needs to be triaged to get a Reaction.
3679     Reaction TriageBreakpoint(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3680     Reaction TriageSyncComplete();
3681     Reaction Triage1stChanceNonSpecial(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3682     Reaction TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3683     Reaction TriageExcep2ndChanceAndInit(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3684     Reaction TriageWin32DebugEvent(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3685 #endif // FEATURE_INTEROP_DEBUGGING
3686
3687     //-----------------------------------------------------------
3688     // Data members
3689     //-----------------------------------------------------------
3690
3691 public:
3692     RSSmartPtr<Cordb>     m_cordb;
3693
3694 private:
3695     // OS process handle to live process. 
3696     // @dbgtodo - , Move this into the Shim. This should only be needed in the live-process
3697     // case. Get rid of this since it breaks the data-target abstraction.
3698     // For Mac debugging, this handle is of course not the real process handle.  This is just a handle to
3699     // wait on for process termination.
3700     HANDLE                m_handle;
3701
3702 public:
3703     // Wrapper to get the OS process handle. This is unsafe because it breaks the data-target abstraction.
3704     // The only things that need this should be calls to DuplicateHandle, and some shimming work.    
3705     HANDLE  UnsafeGetProcessHandle()
3706     {
3707         return m_handle;
3708     }
3709
3710     // Set when code:CordbProcess::Detach is called.
3711     // Public APIs can check this and return CORDBG_E_PROCESS_DETACHED.
3712     // @dbgtodo  managed pipeline - really could merge this with neuter. 
3713     bool                  m_detached;
3714
3715     // True if we code:CordbProcess::Stop is called before the managed CreateProcess event.
3716     // In this case, m_initialized is false, and we can't send an AsyncBreak event to the LS.
3717     // (since the LS isn't going to send a SyncComplete event back since the CLR isn't loaded/ready).
3718     // @dbgtodo  managed pipeline - move into shim, along with Stop/Continue.
3719     bool                  m_uninitializedStop;
3720
3721
3722     // m_exiting is true if we know the LS is starting to exit (if the
3723     // RS is telling the LS to exit) or if we know the LS has already exited.
3724     bool                  m_exiting;
3725
3726
3727     // m_terminated can only be set to true if we know 100% the LS has exited (ie, somebody
3728     // waited on the LS process handle).
3729     bool                  m_terminated;
3730
3731     bool                  m_unrecoverableError;
3732
3733     bool                  m_specialDeferment;
3734     bool                  m_helperThreadDead; // flag used for interop
3735
3736     // This tracks if the loader breakpoint has been received during interop-debugging.
3737     // The Loader Breakpoint is an breakpoint event raised by the OS once the debugger is attached.
3738     // It comes in both Attach and Launch scenarios.
3739     // This is also used in fake-native debugging scenarios.
3740     bool                  m_loaderBPReceived;
3741
3742
3743 private:
3744
3745     // MetaData dispenser. 
3746     RSExtSmartPtr<IMetaDataDispenserEx> m_pMetaDispenser;
3747
3748     //
3749     // Count of the number of outstanding CordbEvals in the process.
3750     //
3751     LONG                  m_cOutstandingEvals;
3752
3753     // Number of oustanding code:CordbHandleValue objects containing 
3754     // Left-side resources. This can be used to tell if ICorDebug needs to
3755     // cleanup gc handles.
3756     LONG                  m_cOutstandingHandles;
3757
3758     // Pointer to the CordbModule instance that can currently change the Jit flags.
3759     // There can be at most one of these. It will represent a module that has just been loaded, before the
3760     // Continue is sent. See code:CordbProcess::RawDispatchEvent and code:CordbProcess::ContinueInternal.
3761     CordbModule * m_pModuleThatCanChangeJitFlags;
3762
3763 public:
3764     LONG OutstandingEvalCount()
3765     {
3766         return m_cOutstandingEvals;
3767     }
3768
3769     void IncrementOutstandingEvalCount()
3770     {
3771         InterlockedIncrement(&m_cOutstandingEvals);
3772     }
3773
3774     void DecrementOutstandingEvalCount()
3775     {
3776         InterlockedDecrement(&m_cOutstandingEvals);
3777     }
3778
3779     LONG OutstandingHandles();
3780     void IncrementOutstandingHandles();
3781     void DecrementOutstandingHandles();
3782
3783     //
3784     // Is it OK to detach at this time
3785     //
3786     HRESULT IsReadyForDetach();
3787
3788     
3789 private:
3790     // This is a target pointer that uniquely identifies the runtime in the target.
3791     // This lets ICD discriminate between multiple CLRs within a single process.
3792     // On windows, this is the base-address of mscorwks.dll in the target.
3793     // If this is 0, then we have V2 semantics where there was only 1 CLR in the target.
3794     // In that case, we can lazily initialize it in code:CordbProcess::CopyManagedEventFromTarget.
3795     // This is just used for backwards compat.
3796     CORDB_ADDRESS         m_clrInstanceId;
3797
3798     // List of things that get neutered on process exit and Continue respectively.
3799     NeuterList            m_ExitNeuterList;
3800     NeuterList            m_ContinueNeuterList;
3801
3802     // List of objects that hold resources into the left-side.
3803     // This is currently for funceval, which cleans up resources in code:CordbEval::SendCleanup.
3804     // @dbgtodo - , (func-eval feature crew): we can get rid of this
3805     // list if we make func-eval not hold resources after it's complete.
3806     LeftSideResourceCleanupList m_LeftSideResourceCleanupList;
3807
3808     // m_stopCount, m_synchronized, & m_syncCompleteReceived are key fields describing
3809     // the processes' sync status.
3810     DWORD                 m_stopCount;
3811
3812     // m_synchronized is the Debugger's view of SyncStatus. It will go high & low for each
3813     // callback. Continue() will set this to false.
3814     // This flag is true roughly from the time that we've dispatched a managed callback
3815     // until the time that it's continued.
3816     bool                  m_synchronized;
3817
3818     // m_syncCompleteReceived tells us if the runtime is _actually_ sychronized. It goes
3819     // high once we get a SyncComplete, and it goes low once we actually send the continue.
3820     // This is always set by the thread that receives the sync-complete. In interop, that's the w32et.
3821     // Thus this is the most accurate indication of wether the Debuggee is _actually_ synchronized or not.
3822     bool                  m_syncCompleteReceived;
3823
3824
3825     // Back pointer to Shim process. This is used for hooks back into the shim.
3826     // If this is Non-null, then we're emulating the V2 case. If this is NULL, then it's the real V3 pipeline.    
3827     RSExtSmartPtr<ShimProcess> m_pShim;
3828
3829     CordbSafeHashTable<CordbThread>           m_userThreads;
3830
3831 public:
3832     ShimProcess* GetShim();
3833
3834     bool                  m_oddSync;
3835
3836
3837     void BuildThreadEnum(CordbBase * pOwnerObj, NeuterList * pOwnerList, RSInitHolder<CordbHashTableEnum> * pHolder);
3838
3839 #ifdef FEATURE_INTEROP_DEBUGGING    
3840     // List of unmanaged threads. This is only populated for interop-debugging.
3841     CordbSafeHashTable<CordbUnmanagedThread>  m_unmanagedThreads;
3842 #endif // FEATURE_INTEROP_DEBUGGING
3843
3844     CordbSafeHashTable<CordbAppDomain>        m_appDomains;
3845
3846     CordbAppDomain * m_sharedAppDomain;
3847
3848     // Since a stepper can begin in one appdomain, and complete in another,
3849     // we put the hashtable here, rather than on specific appdomains.
3850     CordbSafeHashTable<CordbStepper>          m_steppers;
3851
3852     //  Used to figure out if we have to refresh any reference objects
3853     //  on the left side.  Gets incremented each time a continue is called, or
3854     //  global debugee state is modified in some other way.
3855     UINT                  m_continueCounter;
3856
3857     // Used to track whether the DAC cache has been flushed.
3858     // We use this information to determine whether CordbStackWalk instances need to 
3859     // be refreshed. 
3860     UINT                  m_flushCounter;
3861
3862     // The DCB is essentially a buffer area used to temporarily hold information read from the debugger
3863     // control block residing on the LS helper thread. We make no assumptions about the validity of this
3864     // information over time, so before using a value from it on the RS, we will always update this buffer
3865     // with a call to UpdateRightSideDCB. This uses a ReadProcessMemory to get the current information from
3866     // the LS DCB.
3867     DebuggerIPCControlBlock * GetDCB() {return ((m_pEventChannel == NULL) ? NULL : m_pEventChannel->GetDCB());}
3868
3869
3870     DebuggerIPCRuntimeOffsets m_runtimeOffsets;
3871     HANDLE                    m_leftSideEventAvailable;
3872     HANDLE                    m_leftSideEventRead;
3873 #if defined(FEATURE_INTEROP_DEBUGGING)
3874     HANDLE                    m_leftSideUnmanagedWaitEvent;
3875 #endif // FEATURE_INTEROP_DEBUGGING
3876     
3877
3878     // This becomes true when the RS receives its first managed event.
3879     // This goes false in shutdown cases.
3880     // If this is true, we can assume:
3881     // - the CLR is loaded.
3882     // - the IPC block is opened and initialized.
3883     // - DAC is initialized (see code:CordbProcess::IsDacInitialized) 
3884     //
3885     // If this is false, we can assume:
3886     // - the CLR may not be loaded into the target process.
3887     // - We can't send IPC events to the LS (because we can't expect a response)
3888     //
3889     // Many APIs can check this bit and return CORDBG_E_NOTREADY if it's false. 
3890     bool                  m_initialized;
3891
3892 #ifdef _DEBUG
3893     void * m_pDBGLastIPCEventType;
3894 #endif
3895
3896     bool                  m_stopRequested;
3897     HANDLE                m_stopWaitEvent;
3898     RSLock                m_processMutex;
3899
3900 #ifdef FEATURE_INTEROP_DEBUGGING
3901     // The number of threads which are IsFirstChanceHijacked
3902     DWORD m_cFirstChanceHijackedThreads;
3903
3904     CordbUnmanagedEvent  *m_unmanagedEventQueue;
3905     CordbUnmanagedEvent  *m_lastQueuedUnmanagedEvent;
3906     CordbUnmanagedEvent  *m_lastQueuedOOBEvent;
3907     CordbUnmanagedEvent  *m_outOfBandEventQueue;
3908
3909     CordbUnmanagedEvent  *m_lastDispatchedIBEvent;
3910     bool                  m_dispatchingUnmanagedEvent;
3911     bool                  m_dispatchingOOBEvent;
3912     bool                  m_doRealContinueAfterOOBBlock;
3913
3914     enum
3915     {
3916         PS_WIN32_STOPPED           = 0x0001,
3917         PS_HIJACKS_IN_PLACE        = 0x0002,
3918         PS_SOME_THREADS_SUSPENDED  = 0x0004,
3919         PS_WIN32_ATTACHED          = 0x0008,
3920         PS_WIN32_OUTOFBAND_STOPPED = 0x0010,
3921     };
3922
3923     unsigned int          m_state;
3924 #endif // FEATURE_INTEROP_DEBUGGING
3925
3926     // True if we're interop-debugging, else false.
3927     bool IsInteropDebugging();
3928
3929     DWORD                 m_helperThreadId; // helper thread ID calculated from sniffing from UM thread-create events.
3930
3931     // Is the given thread id a helper thread (real or worker?)
3932     bool IsHelperThreadWorked(DWORD tid);
3933
3934     //
3935     // We cache the LS patch table on the RS.
3936     //
3937
3938     // The array of entries. (The patchtable is a hash implemented as a single-array)
3939     // This array includes empty entries.
3940     // There is an auxillary bucket structure used to map hash codes to array indices.
3941     // We traverse the array, and we recognize an empty slot
3942     // if DebuggerControllerPatch::opcode == 0.
3943     // If we haven't gotten the table, then m_pPatchTable is NULL
3944     BYTE*                 m_pPatchTable;
3945
3946     // The number of entries (both used & unused) in m_pPatchTable.
3947     UINT                  m_cPatch;
3948
3949     // so we know where to write the changes patchtable back to
3950     // This has m_cPatch elements.
3951     BYTE                 *m_rgData;
3952
3953     // Cached value of iNext entries such that:
3954     //      m_rgNextPatch[i] = ((DebuggerControllerPatch*)m_pPatchTable)[i]->iNext;
3955     //      where 0 <= i < m_cPatch
3956     // This provides a linked list (via indices) to traverse the used entries of m_pPatchTable.
3957     // This has m_cPatch elements.
3958     ULONG               *m_rgNextPatch;
3959
3960     // This has m_cPatch elements.
3961     PRD_TYPE             *m_rgUncommitedOpcode;
3962
3963     // CORDB_ADDRESS's are UINT_PTR's (64 bit under _WIN64, 32 bit otherwise)
3964 #if defined(DBG_TARGET_WIN64)
3965 #define MAX_ADDRESS     (_UI64_MAX)
3966 #else
3967 #define MAX_ADDRESS     (ULONG_MAX)
3968 #endif
3969 #define MIN_ADDRESS     (0x0)
3970     CORDB_ADDRESS       m_minPatchAddr; //smallest patch in table
3971     CORDB_ADDRESS       m_maxPatchAddr;
3972
3973     // <TODO>@todo port : if slots of CHashTable change, so should these</TODO>
3974 #define DPT_TERMINATING_INDEX (UINT32_MAX)
3975     // Index into m_pPatchTable of the first patch (first used entry).
3976     ULONG                  m_iFirstPatch;
3977
3978     // Initializes the DAC
3979     void InitDac();
3980
3981     // copy new data from LS DCB to RS buffer
3982     void UpdateRightSideDCB();
3983
3984     // copy new data from RS DCB buffer to LS DCB
3985     void UpdateLeftSideDCBField(void * rsFieldAddr, SIZE_T size);
3986
3987     // allocate and initialize the RS DCB buffer
3988     void GetEventBlock(BOOL * pfBlockExists);
3989
3990     IEventChannel * GetEventChannel();
3991
3992     bool SupportsVersion(CorDebugInterfaceVersion featureVersion);
3993
3994     void StartEventDispatch(DebuggerIPCEventType event);
3995     void FinishEventDispatch();
3996     bool AreDispatchingEvent();
3997
3998     HANDLE GetHelperThreadHandle() { return m_hHelperThread; }
3999
4000     CordbAppDomain* GetDefaultAppDomain() { return m_pDefaultAppDomain; }
4001
4002 #ifdef FEATURE_INTEROP_DEBUGGING    
4003     // Lookup if there's a native BP at the given address. Return NULL not found.
4004     NativePatch * GetNativePatch(const void * pAddress);
4005 #endif // FEATURE_INTEROP_DEBUGGING    
4006
4007     bool  IsBreakOpcodeAtAddress(const void * address);
4008
4009 private:
4010     // 
4011     // handle to helper thread. Used for managed debugging.
4012     // Initialized only after we get the tid from the DCB.
4013     HANDLE m_hHelperThread;
4014
4015     DebuggerIPCEventType  m_dispatchedEvent;   // what event are we currently dispatching?
4016
4017     RSLock            m_StopGoLock;
4018
4019     // Each process has exactly one Default AppDomain
4020     // @dbgtodo  appdomain : We should try and simplify things by removing this.
4021     // At the moment it's necessary for CordbProcess::UpdateThreadsForAdUnload.
4022     CordbAppDomain*     m_pDefaultAppDomain;    // owned by m_appDomains
4023
4024 #ifdef FEATURE_INTEROP_DEBUGGING
4025     // Helpers
4026     CordbUnmanagedThread * GetUnmanagedThreadFromEvent(const DEBUG_EVENT * pEvent);
4027 #endif // FEATURE_INTEROP_DEBUGGING
4028
4029     // Ensure we have a CLR Instance ID to debug
4030     HRESULT EnsureClrInstanceIdSet();
4031
4032 #ifdef FEATURE_INTEROP_DEBUGGING
4033     // // The full debug event is too large, so we just remember the important stuff.
4034     struct MiniDebugEvent
4035     {
4036         BYTE code; // event code from the debug event
4037         CordbUnmanagedThread * pUThread; // unmanaged thread this was on.
4038         // @todo - we should have some misc data.
4039         union
4040         {
4041             struct {
4042                 void * pAddress; // address of an exception
4043                 DWORD dwCode;
4044             } ExceptionData;
4045             struct {
4046                 void * pBaseAddress; // for module load & unload
4047             } ModuleData;
4048         } u;
4049     };
4050
4051     // Group fields that are just used for debug support here.
4052     // Some are included even in retail builds to help debug retail failures.
4053     struct DebugSupport
4054     {
4055         // For debugging, we keep a rolling queue of the last N Win32 debug events.
4056         MiniDebugEvent        m_DebugEventQueue[DEBUG_EVENTQUEUE_SIZE];
4057         int                   m_DebugEventQueueIdx;
4058         int                   m_TotalNativeEvents;
4059
4060         // Breakdown of different types of native events
4061         int                   m_TotalIB;
4062         int                   m_TotalOOB;
4063         int                   m_TotalCLR;
4064     } m_DbgSupport;
4065
4066     CUnorderedArray<NativePatch, 10> m_NativePatchList;
4067 #endif // FEATURE_INTEROP_DEBUGGING
4068
4069     //
4070     // DAC
4071     //
4072
4073     // Try to initalize DAC, may fail
4074     BOOL TryInitializeDac();
4075
4076     // Expect DAC initialize to succeed.
4077     void InitializeDac();
4078
4079     
4080     void CreateDacDbiInterface();
4081     
4082     // Free DAC.
4083     void FreeDac();
4084
4085
4086     HModuleHolder             m_hDacModule;    
4087     RSExtSmartPtr<ICorDebugDataTarget> m_pDACDataTarget;
4088
4089     // The mutable version of the data target, or null if read-only
4090     RSExtSmartPtr<ICorDebugMutableDataTarget> m_pMutableDataTarget;
4091
4092     RSExtSmartPtr<ICorDebugMetaDataLocator>   m_pMetaDataLocator;
4093
4094     IDacDbiInterface *  m_pDacPrimitives;
4095
4096     IEventChannel *     m_pEventChannel;
4097
4098     // If true, then we'll ASSERT if we detect the target is corrupt or inconsistent
4099     // This switch is for diagnostics purposes only and should always be false in retail builds.
4100     bool                m_fAssertOnTargetInconsistency;
4101
4102     // When a successful attempt to read runtime offsets from LS occurs, this flag is set.
4103     bool m_runtimeOffsetsInitialized;
4104
4105     // controls how metadata updated in the target is handled
4106     WriteableMetadataUpdateMode m_writableMetadataUpdateMode;
4107 };
4108
4109 // Some IMDArocess APIs are supported as interop-only.
4110 #define FAIL_IF_MANAGED_ONLY(pProcess) \
4111 { CordbProcess * __Proc = pProcess; if (!__Proc->IsInteropDebugging()) return CORDBG_E_MUST_BE_INTEROP_DEBUGGING; }
4112
4113
4114 /* ------------------------------------------------------------------------- *
4115  * Module class
4116  * ------------------------------------------------------------------------- */
4117
4118 class CordbModule : public CordbBase, 
4119                     public ICorDebugModule, 
4120                     public ICorDebugModule2, 
4121                     public ICorDebugModule3
4122 {
4123 public:
4124     CordbModule(CordbProcess *      process,
4125                 VMPTR_Module        vmModule,
4126                 VMPTR_DomainFile    vmDomainFile);
4127
4128     virtual ~CordbModule();
4129     virtual void Neuter();
4130
4131     using CordbBase::GetProcess;
4132
4133 #ifdef _DEBUG
4134     virtual const char * DbgGetName() { return "CordbModule"; }
4135 #endif
4136
4137
4138     //-----------------------------------------------------------
4139     // IUnknown
4140     //-----------------------------------------------------------
4141
4142     ULONG STDMETHODCALLTYPE AddRef()
4143     {
4144         return (BaseAddRef());
4145     }
4146     ULONG STDMETHODCALLTYPE Release()
4147     {
4148         return (BaseRelease());
4149     }
4150     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
4151
4152     //-----------------------------------------------------------
4153     // ICorDebugModule
4154     //-----------------------------------------------------------
4155
4156     COM_METHOD GetProcess(ICorDebugProcess **ppProcess);
4157     COM_METHOD GetBaseAddress(CORDB_ADDRESS *pAddress);
4158     COM_METHOD GetAssembly(ICorDebugAssembly **ppAssembly);
4159     COM_METHOD GetName(ULONG32 cchName, ULONG32 *pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4160     COM_METHOD EnableJITDebugging(BOOL bTrackJITInfo, BOOL bAllowJitOpts);
4161     COM_METHOD EnableClassLoadCallbacks(BOOL bClassLoadCallbacks);
4162
4163     // Gets the latest version of a function given the methodDef token
4164     COM_METHOD GetFunctionFromToken(mdMethodDef methodDef,
4165                                     ICorDebugFunction **ppFunction);
4166     COM_METHOD GetFunctionFromRVA(CORDB_ADDRESS rva, ICorDebugFunction **ppFunction);
4167     COM_METHOD GetClassFromToken(mdTypeDef typeDef,
4168                                  ICorDebugClass **ppClass);
4169     COM_METHOD CreateBreakpoint(ICorDebugModuleBreakpoint **ppBreakpoint);
4170     
4171     // Not implemented - legacy
4172     COM_METHOD GetEditAndContinueSnapshot(
4173         ICorDebugEditAndContinueSnapshot **ppEditAndContinueSnapshot);
4174
4175     COM_METHOD GetMetaDataInterface(REFIID riid, IUnknown **ppObj);
4176     COM_METHOD GetToken(mdModule *pToken);
4177     COM_METHOD IsDynamic(BOOL *pDynamic);
4178     COM_METHOD GetGlobalVariableValue(mdFieldDef fieldDef,
4179                                    ICorDebugValue **ppValue);
4180     COM_METHOD GetSize(ULONG32 *pcBytes);
4181     COM_METHOD IsInMemory(BOOL *pInMemory);
4182
4183     //-----------------------------------------------------------
4184     // ICorDebugModule2
4185     //-----------------------------------------------------------
4186     COM_METHOD SetJMCStatus(
4187         BOOL fIsUserCode,
4188         ULONG32 cOthers,
4189         mdToken others[]);
4190
4191     // Applies an EnC edit to the module
4192     COM_METHOD ApplyChanges(
4193         ULONG  cbMetaData,
4194         BYTE   pbMetaData[],
4195         ULONG  cbIL,
4196         BYTE   pbIL[]);
4197
4198     // Resolve an assembly given an AssemblyRef token. Note that
4199     // this will not trigger the loading of assembly. If assembly is not yet loaded,
4200     // this will return an CORDBG_E_CANNOT_RESOLVE_ASSEMBLY error
4201     COM_METHOD ResolveAssembly(mdToken tkAssemblyRef,
4202                                    ICorDebugAssembly **ppAssembly);
4203
4204     // Sets EnC and optimization flags
4205     COM_METHOD SetJITCompilerFlags(DWORD dwFlags);
4206
4207     // Gets EnC and optimization flags
4208     COM_METHOD GetJITCompilerFlags(DWORD *pdwFlags);
4209
4210     //-----------------------------------------------------------
4211     // ICorDebugModule3
4212     //-----------------------------------------------------------
4213     COM_METHOD CreateReaderForInMemorySymbols(REFIID riid,
4214                                               void** ppObj);
4215
4216     //-----------------------------------------------------------
4217     // Internal members
4218     //-----------------------------------------------------------
4219
4220 #ifdef _DEBUG
4221     // Debug helper to ensure that module is no longer discoverable
4222     void DbgAssertModuleDeleted();
4223 #endif // _DEBUG
4224
4225     // Internal help to get the "name" (filename or pretty name) of the module.
4226     HRESULT GetNameWorker(ULONG32 cchName, ULONG32 *pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4227     
4228     // Marks that the module's metadata has become invalid and needs to be refetched.
4229     void RefreshMetaData();
4230
4231     // Cache the current continue counter as the one that the LoadEvent is
4232     // dispatched in.
4233     void SetLoadEventContinueMarker();
4234
4235     // Return CORDBG_E_MUST_BE_IN_LOAD_MODULE if this module is not in its load callback.
4236     HRESULT EnsureModuleIsInLoadCallback();
4237
4238     BOOL IsDynamic();
4239
4240     // Gets the latest version of the function for the methodDef, if any
4241     CordbFunction * LookupFunctionLatestVersion(mdMethodDef methodToken);
4242
4243     // Gets the latest version of the function. Creates a new instance if none exists yet.
4244     CordbFunction* LookupOrCreateFunctionLatestVersion(mdMethodDef funcMetaDataToken);
4245
4246     // Finds or creates a function for the first time (not for use on EnC if function doesn't exist yet)
4247     CordbFunction * LookupOrCreateFunction(mdMethodDef token, SIZE_T enCVersion);
4248
4249     // Creates an CordbFunction instances for the first time (not for use on EnC)
4250     CordbFunction * CreateFunction(mdMethodDef token, SIZE_T enCVersion);
4251
4252     // Creates a CordbFunction object to represent the specified EnC version 
4253     HRESULT UpdateFunction(mdMethodDef token,
4254                            SIZE_T newEnCVersion,
4255                            CordbFunction** ppFunction);
4256
4257     CordbClass* LookupClass(mdTypeDef classToken);
4258     HRESULT LookupOrCreateClass(mdTypeDef classToken, CordbClass** ppClass);
4259     HRESULT CreateClass(mdTypeDef classToken, CordbClass** ppClass);
4260     HRESULT LookupClassByToken(mdTypeDef token, CordbClass **ppClass);
4261     HRESULT ResolveTypeRef(mdTypeRef token, CordbClass **ppClass);
4262     HRESULT ResolveTypeRefOrDef(mdToken token, CordbClass **ppClass);
4263
4264     // Sends the event to the left side to apply the changes to the debugee
4265     HRESULT ApplyChangesInternal(
4266         ULONG cbMetaData,
4267         BYTE pbMetaData[],
4268         ULONG cbIL,
4269         BYTE pbIL[]);
4270
4271     // Pulls new metadata if needed in order to ensure the availability of
4272     // the given token
4273     void UpdateMetaDataCacheIfNeeded(mdToken token);
4274
4275     HRESULT InitPublicMetaDataFromFile(const WCHAR * pszFullPathName, DWORD dwOpenFlags, bool validateFileInfo);
4276
4277     // Creates a CordbNativeCode (if it's not already created) and adds it to the
4278     // hash table of CordbNativeCodes belonging to the module.
4279     CordbNativeCode * LookupOrCreateNativeCode(mdMethodDef methodToken,
4280                                                VMPTR_MethodDesc methodDesc,
4281                                                CORDB_ADDRESS startAddress);
4282
4283 private:
4284     // Set the metadata (both public and internal) for the module.
4285     void InitMetaData(TargetBuffer buffer, BOOL useFileMappingOptimization);
4286
4287     // Checks if the given token is in the cached metadata
4288     BOOL CheckIfTokenInMetaData(mdToken token);
4289
4290     // Update the public metadata given a buffer in the target.
4291     void UpdatePublicMetaDataFromRemote(TargetBuffer bufferRemoteMetaData);
4292
4293     // Initialize just the public metadata by reading from an on-disk module
4294     HRESULT InitPublicMetaDataFromFile();
4295     // Initialize just the public metadata by reading new metadata from the buffer
4296     void InitPublicMetaData(TargetBuffer buffer);
4297
4298     // Rebuild the internal metadata given the public one.
4299     void UpdateInternalMetaData();
4300
4301     // Determines whether the on-disk metadata for this module is usable as the
4302     // current metadata
4303     BOOL IsFileMetaDataValid();
4304
4305     // Helper to copy metadata buffer from the Target to the host.
4306     void CopyRemoteMetaData(TargetBuffer buffer, CoTaskMemHolder<VOID> * pLocalBuffer);
4307
4308
4309     CordbAssembly * ResolveAssemblyInternal(mdToken tkAssemblyRef);
4310
4311     BOOL IsWinMD();
4312
4313     //-----------------------------------------------------------
4314     // Convenience routines
4315     //-----------------------------------------------------------
4316
4317 public:
4318     CordbAppDomain *GetAppDomain()
4319     {
4320         return m_pAppDomain;
4321     }
4322
4323     CordbAssembly * GetCordbAssembly ();
4324
4325     // Get the module filename, or NULL if none.  Throws on error.
4326     const WCHAR * GetModulePath();
4327
4328     const WCHAR * GetNGenImagePath();
4329
4330     const VMPTR_DomainFile GetRuntimeDomainFile ()
4331     {
4332         return m_vmDomainFile;
4333     }
4334     
4335     const VMPTR_Module GetRuntimeModule()
4336     {
4337         return m_vmModule;
4338     }
4339
4340     // Get symbol stream for in-memory modules.
4341     IDacDbiInterface::SymbolFormat GetInMemorySymbolStream(IStream ** ppStream);
4342
4343     // accessor for PE file
4344     VMPTR_PEFile GetPEFile();
4345
4346
4347     IMetaDataImport * GetMetaDataImporter();
4348
4349     // accessor for Internal MetaData importer.
4350     IMDInternalImport * GetInternalMD();
4351
4352     //-----------------------------------------------------------
4353     // Data members
4354     //-----------------------------------------------------------
4355
4356 public:
4357     CordbAssembly*   m_pAssembly;
4358     CordbAppDomain*  m_pAppDomain;
4359     CordbSafeHashTable<CordbClass>    m_classes;
4360
4361     // A collection, indexed by methodDef, of the latest version of functions in this module
4362     // The collection is filled lazily by LookupOrCreateFunction
4363     CordbSafeHashTable<CordbFunction> m_functions;
4364
4365     // The real handle into the VM for a module. This is appdomain aware.
4366     // This is the primary VM counterpart for the CordbModule.
4367     VMPTR_DomainFile m_vmDomainFile;
4368
4369     VMPTR_Module m_vmModule;
4370
4371     DWORD            m_EnCCount;
4372
4373 private:
4374     
4375     enum ILWinMDState
4376     {
4377         Uninitialized,
4378         False,
4379         True
4380     };
4381
4382     // Base Address and size of this module in debuggee's process. Maybe null if unknown.
4383     TargetBuffer m_PEBuffer;
4384
4385     BOOL             m_fDynamic; // Dynamic modules can grow (like Reflection Emit)
4386     BOOL             m_fInMemory; // In memory modules don't have file-backing.
4387     ILWinMDState     m_isIlWinMD; // WinMD modules don't support all metadata interfaces
4388
4389     // Indicates that the module must serialize its metadata in process as part of metadata
4390     // refresh. This is required for modules updated on the fly by the profiler
4391     BOOL             m_fForceMetaDataSerialize;
4392
4393     // Full path to module's image, if any.  Empty if none, NULL if not yet set.
4394     StringCopyHolder m_strModulePath;
4395
4396     // Full path to the ngen file. Empty if not ngenned, NULL if not yet set.
4397     // This isn't exposed publicly, but we may use it internally for loading metadata.
4398     StringCopyHolder m_strNGenImagePath;
4399
4400     // "Global" class for this module. Global functions + vars exist in this class.
4401     RSSmartPtr<CordbClass> m_pClass;
4402
4403     // Handle to PEFile, useful for metadata lookups.
4404     // this should always be non-null.
4405     VMPTR_PEFile    m_vmPEFile;
4406
4407     
4408     // Public metadata importer. This is lazily initialized and accessed from code:GetMetaDataImporter
4409     // This is handed out to debugger clients via code:CordbModule::GetMetaDataInterface
4410     // This is also tightly coupled to the internal metadata importer, m_pInternalMetaDataImport. 
4411     RSExtSmartPtr<IMetaDataImport> m_pIMImport;
4412
4413     // Internal metadata object. This is closely tied to the public metadata object (m_pIMImport).
4414     // They share the same backing storage, but expose different interfaces to that storage.
4415     // Debugger authors and tools use the public interfaces.
4416     // DAC-ized operations in the VM require an IMDInternalImport. 
4417     // The public and internal must be updated together.
4418     // This ultimately gets handed back to DAC via code:CordbProcess::LookupMetaData
4419     RSExtSmartPtr<IMDInternalImport> m_pInternalMetaDataImport;
4420     
4421     // Continue counter of when the module was loaded.
4422     // See code:CordbModule::SetLoadEventContinueMarker for details
4423     UINT m_nLoadEventContinueCounter;
4424
4425     // This is a table of all NativeCode objects in the module indexed
4426     // by start address
4427     // The collection is filled lazily by LookupOrCreateNativeCode
4428     CordbSafeHashTable<CordbNativeCode> m_nativeCodeTable;
4429 };
4430
4431
4432 //-----------------------------------------------------------------------------
4433 // Cordb MDA notification
4434 //-----------------------------------------------------------------------------
4435 class CordbMDA : public CordbBase, public ICorDebugMDA
4436 {
4437 public:
4438     CordbMDA(CordbProcess * pProc, DebuggerMDANotification * pData);
4439     ~CordbMDA();
4440
4441     virtual void Neuter();
4442
4443 #ifdef _DEBUG
4444     virtual const char * DbgGetName() { return "CordbMDA"; }
4445 #endif
4446
4447     //-----------------------------------------------------------
4448     // IUnknown
4449     //-----------------------------------------------------------
4450
4451     ULONG STDMETHODCALLTYPE AddRef()
4452     {
4453         return (BaseAddRefEnforceExternal());
4454     }
4455     ULONG STDMETHODCALLTYPE Release()
4456     {
4457         return (BaseReleaseEnforceExternal());
4458     }
4459     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
4460
4461     //-----------------------------------------------------------
4462     // ICorDebugMDA
4463     //-----------------------------------------------------------
4464
4465     // Get the string for the type of the MDA. Never empty.
4466     // This is a convenient performant alternative to getting the XML stream and extracting
4467     // the type from that based off the schema.
4468     COM_METHOD GetName(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4469
4470     // Get a string description of the MDA. This may be empty (0-length).
4471     COM_METHOD GetDescription(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4472
4473     // Get the full associated XML for the MDA. This may be empty.
4474     // This could be a potentially expensive operation if the xml stream is large.
4475     // See the MDA documentation for the schema for this XML stream.
4476     COM_METHOD GetXML(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4477
4478     COM_METHOD GetFlags(CorDebugMDAFlags * pFlags);
4479
4480     // Thread that the MDA is fired on. We use the os tid instead of an ICDThread in case an MDA is fired on a
4481     // native thread (or a managed thread that hasn't yet entered managed code and so we don't have a ICDThread
4482     // object for it yet)
4483     COM_METHOD GetOSThreadId(DWORD * pOsTid);
4484
4485 private:
4486     NewArrayHolder<WCHAR> m_szName;
4487     NewArrayHolder<WCHAR> m_szDescription;
4488     NewArrayHolder<WCHAR> m_szXml;
4489
4490     DWORD m_dwOSTID;
4491     CorDebugMDAFlags m_flags;
4492 };
4493
4494
4495
4496 struct CordbHangingField
4497 {
4498     FREEHASHENTRY   entry;
4499     FieldData data;
4500 };
4501
4502 // A hashtable for storing EnC hanging field information
4503 // FieldData.m_fldMetadataToken is the key
4504 class CordbHangingFieldTable : public CHashTableAndData<CNewDataNoThrow>
4505 {
4506   private:
4507
4508     BOOL Cmp(SIZE_T k1, const HASHENTRY *pc2)
4509     {
4510         LIMITED_METHOD_CONTRACT;  
4511         return (ULONG)(UINT_PTR)(k1) != 
4512                (reinterpret_cast<const CordbHangingField *>(pc2))->data.m_fldMetadataToken; 
4513     }
4514
4515     ULONG HASH(mdFieldDef fldToken)
4516     {
4517         LIMITED_METHOD_CONTRACT;  
4518         return fldToken; 
4519     }
4520
4521     SIZE_T KEY(mdFieldDef fldToken)
4522     { 
4523         return (SIZE_T)fldToken; 
4524     }
4525
4526   public:
4527
4528 #ifndef DACCESS_COMPILE
4529
4530     CordbHangingFieldTable() : CHashTableAndData<CNewDataNoThrow>(11)
4531     {
4532         NewInit(11, sizeof(CordbHangingField), 11);
4533     }
4534
4535     FieldData * AddFieldInfo(FieldData * pInfo)
4536     {
4537         _ASSERTE(pInfo != NULL);
4538
4539         CordbHangingField *pEntry = (CordbHangingField *)Add(HASH(pInfo->m_fldMetadataToken));
4540         pEntry->data = *pInfo; // copy everything over
4541
4542         // Return a pointer to the data
4543         return &(pEntry->data);
4544     }
4545
4546     void RemoveFieldInfo(mdFieldDef fldToken)
4547     {
4548         CordbHangingField *entry = (CordbHangingField*)Find(HASH(fldToken), KEY(fldToken));
4549         _ASSERTE(entry != NULL);
4550         Delete(HASH(fldToken), (HASHENTRY*)entry);
4551    }
4552
4553 #endif // #ifndef DACCESS_COMPILE
4554
4555     FieldData * GetFieldInfo(mdFieldDef fldToken)
4556     {
4557         CordbHangingField * entry = (CordbHangingField *)Find(HASH(fldToken), KEY(fldToken));
4558         return (entry!=NULL?&(entry->data):NULL);
4559     }
4560 };
4561
4562
4563 /* ------------------------------------------------------------------------- *
4564  * Instantiation.
4565  *
4566  * This struct stores a set of type parameters.  It is used in
4567  * the heap-allocated data structures CordbType and CordbNativeCode.
4568  *
4569  *   CordbType::m_inst.    Stores the class type parameters if any,
4570  *                         or the solitary array type parameter, or the solitary parameter
4571  *                         to a byref type.
4572  *
4573  *   CordbJITILFrame::m_genericArgs.  Stores exact generic parameters for the generic method frame if available
4574  *                                 Need not be identicial if code is shared between generic instantiations.
4575  *                                 May be inexact if real instantiation has been optimized away off
4576  *                                 the frame (nb this gets reported by the left side)
4577  *  
4578  * This is conceptually an array of Type-parameters, with the split (m_cClassTyPars) between
4579  * where the Type's type-parameters end and the Method's type-parameters begin.
4580  * ------------------------------------------------------------------------- */
4581 class Instantiation
4582 {
4583 public:
4584     // Empty ctor
4585     Instantiation()
4586         : m_cInst(0), m_ppInst(NULL), m_cClassTyPars (0)
4587     { }
4588
4589     // Instantiation for Type. 0 Method type-parameters.
4590     Instantiation(unsigned int _cClassInst, CordbType **_ppClassInst)
4591         : m_cInst(_cClassInst), m_ppInst(_ppClassInst), m_cClassTyPars(_cClassInst)
4592     {LIMITED_METHOD_CONTRACT;  }
4593
4594     // Instantiation for Type + Function.
4595     Instantiation(unsigned int _cInst, CordbType **_ppInst, unsigned int numClassTyPars)
4596         : m_cInst(_cInst), m_ppInst(_ppInst),
4597         m_cClassTyPars (numClassTyPars)
4598     { }
4599
4600     // Copy constructor.
4601     Instantiation(const Instantiation &inst)
4602         : m_cInst(inst.m_cInst), m_ppInst(inst.m_ppInst), m_cClassTyPars (inst.m_cClassTyPars)
4603     { }
4604
4605     // Number of elements in array pointed to by m_ppInst
4606     unsigned int m_cInst;
4607
4608     // Pointer to array of CordbType objects. Length of array is m_cInst.    
4609     // Array is Class Type parameters followed by Function's Type parameters.
4610     // Eg, Instantiation for Class<Foo, Goo>::Func<Bar> would be {Foo, Goo, Bar}. 
4611     // m_cInst = 3, m_cClassTyPars = 2. 
4612     // In contrast, Instantiation for Class::Func<Foo, Goo, Bar> would have same
4613     // array, but m_cClassTyPars = 0.
4614     CordbType **m_ppInst;
4615
4616     // Track the split between Type vs. Method type-params. 
4617     unsigned int m_cClassTyPars;
4618 };
4619
4620 //------------------------------------------------------------------------
4621 // CordbType: replaces the use of signatures.
4622 //
4623 // Left Side & Right Side
4624 // ---------------------------
4625 // CordbTypes may come from either the Right Side (via being built up from
4626 //   ICorDebug), or from the Left-Side (being handed back from LS operations
4627 //   like getting the type from an Object the LS handed back).
4628 // The RightSide CordbType corresponds to a Left-Side TypeHandle.
4629 // CordbTypes are communicated across the LS/RS boundary by marshalling
4630 // to BasicTypeData + ExpandedTypeData IPC events.
4631 // 
4632 //
4633 // Invariants on CordbType
4634 // ---------------------------
4635 //
4636 //   The m_elementType is NEVER ELEMENT_TYPE_VAR or ELEMENT_TYPE_MVAR or ELEMENT_TYPE_GENERICINST
4637 //   CordbTypes are always _ground_ types (fully instantiated generics or non-generic types). If 
4638 //   they represent an instantiated type like List<int> then m_inst will be non-empty.
4639 //   
4640 //
4641 //   !!!! The m_elementType is NEVER ELEMENT_TYPE_VALUETYPE !!!!
4642 //   !!!! To find out if it is a value type call CordbType::IsValueType() !!!!
4643 //
4644 // Where CordbTypes are stored
4645 // ---------------------------
4646 //
4647 // Because we could have a significant number of different instantiations for a given templated type, 
4648 // we need an efficient way to store and retrieve the CordbType instances for these instantiations.
4649 // For this reason, we use a tree-like scheme to hash-cons types. To implement this we use the following
4650 // scheme:
4651 //   - CordbTypes are created for "partially instantiated" types,
4652 //     e.g. CordbTypes exist for "Dict" and "Dict<int>" even if the real
4653 //     type being manipulated by the user is "Dict<int,string>"
4654 //   - Subordinate types (E.g. Dict<int,string> is subordinate to Dict<int>,
4655 //     which is itself subordinate to the type for Dict) get stored
4656 //     in the m_spinetypes hash table of the parent type.
4657 //   - In m_spinetypes the pointers of the CordbTypes themselves
4658 //     are used for the unique ids for entries in the table.
4659 // Note that CordbType instances that are created for "partially instantiated" types 
4660 // are never used for any purpose other than efficient hashing. Specifically, the debugger will
4661 // never have reason to expose a partially instantiated type outside of the hashing algorithm.
4662 //
4663 // CordbTypes have object identity: if 2 CordbTypes represent the same type (in the same AppDomain),
4664 // then they will be the same CordbType instance.
4665 //
4666 // Thus the representation for  "Dict<class String,class Foo, class Foo* >" goes as follows:
4667 //    1. Assume the type Foo is represented by CordbClass *5678x
4668 //    1b. Assume the hashtable m_sharedtypes in the AppDomain maps E_T_STRING to the CordbType *0ABCx
4669 //       Assume m_type in class Foo (i.e. CordbClass *5678x) is the CordbType *0DEFx
4670 //       Assume m_type in class Foo maps E_T_PTR to the CordbType *0647x
4671 //    2. The hash table m_spinetypes in "Dict" maps "0ABCx" to a new CordbType
4672 //       representing Dict<String> (a single type application)
4673 //    3. The hash table m_spinetypes in this new CordbType maps "0DEFx" to a
4674 //        new CordbType representing Dict<class String,class Foo>
4675 //    3. The hash table m_spinetypes in this new CordbType maps "0647" to a
4676 //        new CordbType representing Dict<class String,class Foo, class Foo*>
4677 //
4678 // This lets us reuse the existing hash table scheme to build
4679 // up instantiated types of arbitrary size.
4680 //
4681 // Array types are similar, excpet that they start with a head type
4682 // for the "type constructor", e.g. "_ []" is a type constructor with rank 1
4683 // and m_elementType = ELEMENT_TYPE_SZARRAY.  These head constructors are
4684 // stored in the m_sharedtypes table in the appdomain.  The actual instantiations
4685 // of the array types are then subordinate types to the array constructor type.
4686 //
4687 // Other types are simpler, and have unique objects stored in the m_sharedtypes
4688 // table in the appdomain.  This table is indexed by CORDBTYPE_ID in RsType.cpp
4689 //
4690 //
4691 // Memory Management of CordbTypes
4692 // ---------------------------
4693 // All CordbTypes are ultimately stored off the CordbAppDomain object.
4694 // The most common place is in the AppDomain's neuter-list. 
4695 //
4696 // See definition of ICorDebugType for further invariants on types.
4697 //
4698
4699 class CordbType : public CordbBase, public ICorDebugType, public ICorDebugType2
4700 {
4701 public:
4702     CordbType(CordbAppDomain *appdomain, CorElementType ty, unsigned int rank);
4703     CordbType(CordbAppDomain *appdomain, CorElementType ty, CordbClass *c);
4704     CordbType(CordbType *tycon, CordbType *tyarg);
4705     virtual ~CordbType();
4706     virtual void Neuter();
4707
4708 #ifdef _DEBUG
4709     virtual const char * DbgGetName() { return "CordbType"; }
4710 #endif
4711
4712     // If you want to force the init to happen even if we think the class
4713     // is up to date, set fForceInit to TRUE
4714     HRESULT Init(BOOL fForceInit);
4715
4716     //-----------------------------------------------------------
4717     // IUnknown
4718     //-----------------------------------------------------------
4719
4720     ULONG STDMETHODCALLTYPE AddRef();
4721     ULONG STDMETHODCALLTYPE Release();
4722     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
4723
4724     //-----------------------------------------------------------
4725     // ICorDebugType
4726     //-----------------------------------------------------------
4727
4728     COM_METHOD GetType(CorElementType *ty);
4729     COM_METHOD GetClass(ICorDebugClass **ppClass);
4730     COM_METHOD EnumerateTypeParameters(ICorDebugTypeEnum **ppTyParEnum);
4731     COM_METHOD GetFirstTypeParameter(ICorDebugType **ppType);
4732     COM_METHOD GetBase(ICorDebugType **ppType);
4733     COM_METHOD GetStaticFieldValue(mdFieldDef fieldDef,
4734                                    ICorDebugFrame * pFrame,
4735                                    ICorDebugValue ** ppValue);
4736     COM_METHOD GetRank(ULONG32 *pnRank);
4737
4738     //-----------------------------------------------------------
4739     // ICorDebugType2
4740     //-----------------------------------------------------------
4741     COM_METHOD GetTypeID(COR_TYPEID *pId);
4742     
4743     //-----------------------------------------------------------
4744     // Non-COM members
4745     //-----------------------------------------------------------
4746
4747     //-----------------------------------------------------------
4748     // Basic constructor operations for the algebra of types.
4749     // These all create unique objects within an AppDomain.
4750     //-----------------------------------------------------------
4751
4752     // This one is used to create simple types, e.g. int32, int64, typedbyref etc.
4753     static HRESULT MkType(CordbAppDomain * pAppDomain, 
4754                           CorElementType elementType, 
4755                           CordbType ** ppResultType);
4756
4757     // This one is used to create array, pointer and byref types
4758     static HRESULT MkType(CordbAppDomain * pAppDomain, 
4759                           CorElementType elementType, 
4760                           ULONG rank, 
4761                           CordbType * pType, 
4762                           CordbType ** ppResultType);
4763
4764     // This one is used to create function pointer types.  et must be ELEMENT_TYPE_FNPTR
4765     static HRESULT MkType(CordbAppDomain * pAppDomain, 
4766                           CorElementType elementType, 
4767                           const Instantiation * pInst, 
4768                           CordbType ** ppResultType);
4769
4770     // This one is used to class and value class types, e.g. "class MyClass" or "class ArrayList<int>"
4771     static HRESULT MkType(CordbAppDomain * pAppDomain, 
4772                           CorElementType elementType, 
4773                           CordbClass * pClass, 
4774                           const Instantiation * pInst, 
4775                           CordbType ** ppResultType);
4776
4777     // Some derived constructors...  Use this one if the type is definitely not
4778     // a paramterized type, e.g. to implement functions on the API where types cannot
4779     // be parameterized.
4780     static HRESULT MkUnparameterizedType(CordbAppDomain *appdomain, CorElementType et, CordbClass *cl, CordbType **ppType);
4781
4782     //-----------------------------------------------------------
4783     // Basic destructor operations over the algebra
4784     //-----------------------------------------------------------
4785     void DestUnaryType(CordbType **pRes) ;
4786     void DestConstructedType(CordbClass **pClass, Instantiation *pInst);
4787     void DestNaryType(Instantiation *pInst);
4788
4789     CorElementType GetElementType() { return m_elementType; }
4790     VMPTR_DomainFile GetDomainFile();
4791     VMPTR_Module GetModule();
4792
4793     // If this is a ptr type, get the CordbType that it points to.
4794     // Eg, for CordbType("Int*"), returns CordbType("Int").
4795     // If not a ptr type, returns null.
4796     // Since it's all internal, no reference counting.
4797     // This is effectively a specialized version of DestUnaryType.
4798     CordbType * GetPointerElementType();
4799
4800
4801     // Create a type from metadata
4802     static HRESULT SigToType(CordbModule * pModule, SigParser * pSigParser, const Instantiation * pInst, CordbType ** ppResultType);
4803
4804     // Create a type from from the data received from the left-side
4805     static HRESULT TypeDataToType(CordbAppDomain *appdomain, DebuggerIPCE_ExpandedTypeData *data, CordbType **pRes);
4806     static HRESULT TypeDataToType(CordbAppDomain *appdomain, DebuggerIPCE_BasicTypeData *data, CordbType **pRes);
4807     static HRESULT InstantiateFromTypeHandle(CordbAppDomain * appdomain, 
4808                                              VMPTR_TypeHandle vmTypeHandle, 
4809                                              CorElementType et, 
4810                                              CordbClass * tycon,   
4811                                              CordbType ** pRes);
4812
4813     // Prepare data to send back to left-side during Init() and FuncEval.  Fail if the the exact
4814     // type data is requested but was not fetched correctly during Init()
4815     HRESULT TypeToBasicTypeData(DebuggerIPCE_BasicTypeData *data);
4816     void TypeToExpandedTypeData(DebuggerIPCE_ExpandedTypeData *data);
4817     void TypeToTypeArgData(DebuggerIPCE_TypeArgData *data);
4818
4819     void CountTypeDataNodes(unsigned int *count);
4820     static void CountTypeDataNodesForInstantiation(unsigned int genericArgsCount, ICorDebugType *genericArgs[], unsigned int *count);
4821     static void GatherTypeData(CordbType *type, DebuggerIPCE_TypeArgData **curr_tyargData);
4822     static void GatherTypeDataForInstantiation(unsigned int genericArgsCount, ICorDebugType *genericArgs[], DebuggerIPCE_TypeArgData **curr_tyargData);
4823
4824     HRESULT GetParentType(CordbClass * baseClass, CordbType ** ppRes);
4825
4826     // These are available after Init() has been called....
4827     HRESULT GetUnboxedObjectSize(ULONG32 *res);
4828     HRESULT GetFieldInfo(mdFieldDef fldToken, FieldData ** ppFieldData);
4829
4830     CordbAppDomain *GetAppDomain() { return m_appdomain; }
4831
4832     bool IsValueType();
4833
4834     // Is this type a GC-root.
4835     bool IsGCRoot();
4836
4837 #ifdef FEATURE_64BIT_ALIGNMENT
4838     // checks if the type requires 8-byte alignment.
4839     // this is not exposed via ICorDebug at present.
4840     HRESULT CordbType::RequiresAlign8(BOOL* isRequired);
4841 #endif
4842
4843     //-----------------------------------------------------------
4844     // Data members
4845     //-----------------------------------------------------------
4846
4847 public:
4848     // Internal representation of the element type. This may not map exactly to the public element type.
4849     // Specifically, m_elementType is NEVER: 
4850     //  ELEMENT_TYPE_VAR, ELEMENT_TYPE_MVAR, ELEMENT_TYPE_GENERICINST, 
4851     //  or ELEMENT_TYPE_VALUETYPE.
4852     // To find out if this CordbType corresponds to a value type (instead of Reference type) call CordbType::IsValueType()
4853     CorElementType                 m_elementType;
4854
4855     // The appdomain that this type lives in. Types (and their type-parameters) are all contained in a single appdomain.
4856     // (alhtough the types may be from different modules).
4857     // This is valid for all CordbType objects, regardless of m_elementType;
4858     CordbAppDomain *               m_appdomain; 
4859
4860     // The matching class for this type.
4861     // Initially only set for E_T_CLASS, lazily computed for E_T_STRING and E_T_OBJECT if needed
4862     CordbClass *                   m_pClass; 
4863
4864     ULONG m_rank; // Only set for E_T_ARRAY etc.
4865
4866     // Array of Type Parameters for this Type.
4867     Instantiation                  m_inst;
4868
4869     // A unique mapping from CordbType objects that are type parameters to CordbType objects.  Each mapping
4870     // represents the use of the containing type as type constructor.  e.g. If the containing type
4871     // is CordbType(CordbClass "List") then the table here will map parameters such as (CordbType(CordbClass "String")) to
4872     // the constructed type CordbType(CordbClass "List", <CordbType(CordbClass "String")>)
4873     // @dbgtodo  synchronization - this is currently protected by the Stop-Go lock. Transition to process-lock.
4874     CordbSafeHashTable<CordbType>  m_spinetypes; 
4875
4876     // Valid after Init(), only for E_T_ARRAY etc.and E_T_CLASS when m_pClass->m_classInfo.m_genericArgsCount > 0.
4877     // m_typeHandleExact is the precise Runtime type handle for this type.
4878     VMPTR_TypeHandle               m_typeHandleExact;
4879
4880     // Valid after Init(), only for E_T_CLASS, and when m_pClass->m_classInfo.m_genericArgsCount > 0.  
4881     // May not be set correctly if m_fieldInfoNeedsInit.
4882     SIZE_T                         m_objectSize;
4883
4884     // DON'T KEEP POINTERS TO ELEMENTS OF m_pFields AROUND!!
4885     // This may be deleted if the class gets EnC'd.
4886     //
4887     // Valid after Init(), only for E_T_CLASS, and when m_pClass->m_classInfo.m_genericArgsCount > 0
4888     // All fields will be valid if we have m_typeHandleExact.
4889     // 
4890     // Only some fields will be valid if we have called Init() but still have m_fieldInfoNeedsInit.
4891     DacDbiArrayList<FieldData>     m_fieldList;
4892
4893     HRESULT ReturnedByValue();
4894
4895 private:
4896     static HRESULT MkTyAppType(CordbAppDomain * pAddDomain, 
4897                                CordbType * pType, 
4898                                const Instantiation * pInst, 
4899                                CordbType ** pResultType);
4900
4901     BOOL                    m_fieldInfoNeedsInit;
4902
4903 private:
4904     HRESULT InitInstantiationTypeHandle(BOOL fForceInit);
4905     HRESULT InitInstantiationFieldInfo(BOOL fForceInit);
4906     HRESULT InitStringOrObjectClass(BOOL fForceInit);
4907 };
4908
4909 /* ------------------------------------------------------------------------- *
4910  * Class class
4911  * ------------------------------------------------------------------------- */
4912
4913 class CordbClass : public CordbBase, public ICorDebugClass, public ICorDebugClass2
4914 {
4915 public:
4916     CordbClass(CordbModule* m, mdTypeDef token);
4917     virtual ~CordbClass();
4918     virtual void Neuter();
4919
4920     using CordbBase::GetProcess;
4921
4922 #ifdef _DEBUG
4923     virtual const char * DbgGetName() { return "CordbClass"; }
4924 #endif
4925
4926
4927     //-----------------------------------------------------------
4928     // IUnknown
4929     //-----------------------------------------------------------
4930
4931     ULONG STDMETHODCALLTYPE AddRef()
4932     {
4933         return (BaseAddRef());
4934     }
4935     ULONG STDMETHODCALLTYPE Release()
4936     {
4937         return (BaseRelease());
4938     }
4939     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
4940
4941     //-----------------------------------------------------------
4942     // ICorDebugClass
4943     //-----------------------------------------------------------
4944
4945     COM_METHOD GetStaticFieldValue(mdFieldDef fieldDef,
4946                                    ICorDebugFrame *pFrame,
4947                                    ICorDebugValue **ppValue);
4948     COM_METHOD GetModule(ICorDebugModule **pModule);
4949     COM_METHOD GetToken(mdTypeDef *pTypeDef);
4950     //-----------------------------------------------------------
4951     // ICorDebugClass2
4952     //-----------------------------------------------------------
4953     COM_METHOD GetParameterizedType(CorElementType elementType,
4954                                     ULONG32 cTypeArgs, 
4955                                     ICorDebugType * rgpTypeArgs[], 
4956                                     ICorDebugType ** ppType);
4957
4958     COM_METHOD SetJMCStatus(BOOL fIsUserCode);
4959
4960     //-----------------------------------------------------------
4961     // Convenience routines and Accessors
4962     //-----------------------------------------------------------
4963
4964     // Helper to get containing module
4965     CordbModule * GetModule()
4966     {
4967         return m_pModule;
4968     }
4969
4970     // get the metadata token for this class
4971     mdTypeDef GetToken() { return m_token; }
4972
4973     // Helper to get the AppDomain the class lives in.
4974     CordbAppDomain * GetAppDomain()
4975     {
4976         return m_pModule->GetAppDomain();
4977     }
4978
4979     // This only very roughly resembles the CLASS_LOAD_LEVEL concept in the VM.
4980     // because DBI's needs are far more coarse grained. Also DBI 
4981     // may contain more, equal, or less information than what is available in
4982     // native runtime data structures. We can have less when we are being lazy
4983     // and haven't yet fetched it. We can have more if use an independent data
4984     // source such as the metadata blob and then compute some type data ourselves
4985     typedef enum 
4986     {
4987         // At this state the constructor has been run. 
4988         // m_module and m_token will be valid
4989         Constructed,
4990
4991         // At this state we have additionally certain to have initialized
4992         // m_fIsValueClass and m_fHasTypeParams
4993         // Calls to IsValueClass() and HasTypeParams() are valid
4994         // This stage should be achievable as long as a runtime type handle
4995         // exists, even if it is unrestored
4996         BasicInfo,
4997
4998         //Everything is loaded, or at least anything created lazily from this
4999         //point on should be certain to succeed (ie m_type)
5000         FullInfo
5001     }
5002     ClassLoadLevel;
5003
5004     ClassLoadLevel GetLoadLevel()
5005     {
5006         return m_loadLevel;
5007     }
5008
5009     // determine if a load event has been sent for this class
5010     BOOL LoadEventSent() { return m_fLoadEventSent; }
5011
5012     // set value of m_fLoadEventSent
5013     void SetLoadEventSent(BOOL fEventSent) { m_fLoadEventSent = fEventSent; }
5014
5015     // determine if the class has been unloaded
5016     BOOL HasBeenUnloaded() { return m_fHasBeenUnloaded; }
5017
5018     // set value of m_fHasBeenUnloaded
5019     void SetHasBeenUnloaded(BOOL fUnloaded) { m_fHasBeenUnloaded = (fUnloaded == TRUE); }
5020
5021     // determine if this is a value class
5022     BOOL IsValueClassNoInit() { return m_fIsValueClass; }
5023
5024     // set value of m_fIsValueClass
5025     void SetIsValueClass(BOOL fIsValueClass) { m_fIsValueClass = (fIsValueClass == TRUE); }
5026
5027     // determine if the value class is known
5028     BOOL IsValueClassKnown() { return m_fIsValueClassKnown; }
5029
5030     // set value of m_fIsValueClassKnown
5031     void SetIsValueClassKnown(BOOL fIsValueClassKnown) { m_fIsValueClassKnown = (fIsValueClassKnown == TRUE); }
5032
5033     // get value of m_type
5034     CordbType * GetType() { return m_type; }
5035
5036     void SetType(CordbType * pType) { m_type.Assign(pType); }
5037
5038     // get the type parameter count
5039     bool HasTypeParams() { _ASSERTE(m_loadLevel >= BasicInfo); return m_fHasTypeParams; }
5040
5041     // get the object size
5042     SIZE_T ObjectSize() { return m_classInfo.m_objectSize; }
5043
5044     // get the metadata token for this class
5045     mdTypeDef MDToken() { return m_token; }
5046
5047     // get the number of fields
5048     unsigned int FieldCount() { return m_classInfo.m_fieldList.Count(); }
5049
5050     //-----------------------------------------------------------
5051     // Functionality shared for CordbType and CordbClass
5052     //-----------------------------------------------------------
5053
5054     static HRESULT SearchFieldInfo(CordbModule *                module,
5055                                    DacDbiArrayList<FieldData> * pFieldList,
5056                                    mdTypeDef                    classToken,
5057                                    mdFieldDef                   fldToken,
5058                                    FieldData **                 ppFieldData);
5059
5060     static HRESULT GetStaticFieldValue2(CordbModule *         pModule,
5061                                         FieldData *           pFieldData,
5062                                         BOOL                  fEnCHangingField,
5063                                         const Instantiation * pInst,
5064                                         ICorDebugFrame *      pFrame, 
5065                                         ICorDebugValue **     ppValue);
5066
5067     //-----------------------------------------------------------
5068     // Non-COM methods
5069     //-----------------------------------------------------------
5070
5071     // Get information about a field that was added by EnC
5072     HRESULT GetEnCHangingField(mdFieldDef         fldToken,
5073                                FieldData **       ppFieldData,
5074                                CordbObjectValue * pObject);
5075
5076 private:
5077     // Get information via the DAC about a field added with Edit and Continue.
5078     FieldData * GetEnCFieldFromDac(BOOL               fStatic,
5079                                    CordbObjectValue * pObject,
5080                                    mdFieldDef         fieldToken);
5081
5082     // Initialize an instance of EnCHangingFieldInfo.
5083     void InitEnCFieldInfo(EnCHangingFieldInfo * pEncField, 
5084                           BOOL                  fStatic,
5085                           CordbObjectValue *    pObject, 
5086                           mdFieldDef            fieldToken, 
5087                           mdTypeDef             classToken);
5088
5089
5090 public:
5091
5092     // set or clear the custom notifications flag to control whether we ignore custom debugger notifications
5093     void SetCustomNotifications(BOOL fEnable) { m_fCustomNotificationsEnabled = fEnable; }
5094     BOOL CustomNotificationsEnabled () { return m_fCustomNotificationsEnabled; }
5095
5096     HRESULT GetFieldInfo(mdFieldDef fldToken, FieldData ** ppFieldData);
5097
5098     // If you want to force the init to happen even if we think the class
5099     // is up to date, set fForceInit to TRUE
5100     void Init(ClassLoadLevel desiredLoadLevel = FullInfo);
5101
5102     // determine if any fields for a type are unallocated statics
5103     BOOL GotUnallocatedStatic(DacDbiArrayList<FieldData> * pFieldList);
5104
5105     bool IsValueClass();
5106     HRESULT GetThisType(const Instantiation * pInst, CordbType ** ppResultType);
5107     static HRESULT PostProcessUnavailableHRESULT(HRESULT hr,
5108                                IMetaDataImport *pImport,
5109                                mdFieldDef fieldDef);
5110     mdTypeDef GetTypeDef() { return (mdTypeDef)m_id; }
5111
5112 #ifdef EnC_SUPPORTED
5113     // when we get an added field or method, mark the class to force re-init when we access it
5114     void MakeOld()
5115     {
5116         m_loadLevel = Constructed;
5117     }
5118 #endif // EnC_SUPPORTED
5119
5120     //-----------------------------------------------------------
5121     // Data members
5122     //-----------------------------------------------------------
5123 private:
5124     // contains information about the type: size and 
5125     // field information
5126     ClassInfo                m_classInfo; 
5127
5128     ClassLoadLevel           m_loadLevel;
5129
5130     // @dbgtodo  managed pipeline - can we get rid of both of these fields?
5131     BOOL                     m_fLoadEventSent;
5132     bool                     m_fHasBeenUnloaded;
5133
5134     // [m_type] is the type object for when this class is used
5135     // as a type.  If the class is a value class then it can represent
5136     // either the boxed or unboxed type - it depends on the context where the
5137     // type is used.  For example on a CordbBoxValue it represents the type of the
5138     // boxed VC, on a CordbVCObjectValue it represents the type of the unboxed VC.
5139     //
5140     // The type field starts of NULL as there
5141     // is no need to create the type object until it is needed.
5142     RSSmartPtr<CordbType>    m_type;
5143
5144     // Module that this Class lives in. Valid at the Constructed type level.
5145     CordbModule *            m_pModule;
5146
5147     // the token for the type constructor - m_id cannot be used for constructed types
5148     // valid at the Constructed type level
5149     mdTypeDef                m_token;  
5150  
5151     // Whether the class is a VC or not is discovered either by
5152     // seeing the class used in a signature after ELEMENT_TYPE_VALUETYPE
5153     // or ELEMENT_TYPE_CLASS or by going and asking the EE.
5154     bool                     m_fIsValueClassKnown;
5155
5156     // Whether the class is a VC or not
5157     bool                     m_fIsValueClass;
5158
5159     // Whether the class has generic type parameters in its definition
5160     bool                     m_fHasTypeParams;
5161
5162     // Timestamp from GetProcess()->m_continueCounter, which we can use to tell if 
5163     // the process has been continued since we last took a snapshot.
5164     UINT                     m_continueCounterLastSync;
5165
5166     // if we add static fields with EnC after this class is loaded (in the debuggee), 
5167     // their value will be hung off the FieldDesc.  Hold information about such fields here.
5168     CordbHangingFieldTable   m_hangingFieldsStatic;
5169
5170     // this indicates whether we should send custom debugger notifications
5171     BOOL                    m_fCustomNotificationsEnabled;
5172
5173 };
5174
5175
5176 /* ------------------------------------------------------------------------- *
5177  * TypeParameter enumerator class
5178  * ------------------------------------------------------------------------- */
5179
5180 class CordbTypeEnum : public CordbBase, public ICorDebugTypeEnum
5181 {
5182 public:
5183     // Factory method: Create a new instance of this class.  Returns NULL on out-of-memory.
5184     // On success, returns a new initialized instance of CordbTypeEnum with ref-count 0 (just like a ctor).
5185     // the life expectancy of the enumerator varies by caller so we require them to specify the applicable neuter list here.
5186     static CordbTypeEnum* Build(CordbAppDomain * pAppDomain, NeuterList * pNeuterList, unsigned int cTypars, CordbType **ppTypars);
5187     static CordbTypeEnum* Build(CordbAppDomain * pAppDomain, NeuterList * pNeuterList, unsigned int cTypars, RSSmartPtr<CordbType>*ppTypars);
5188
5189     virtual ~CordbTypeEnum() ;
5190
5191     virtual void Neuter();
5192
5193
5194 #ifdef _DEBUG
5195     virtual const char * DbgGetName() { return "CordbTypeEnum"; }
5196 #endif
5197
5198
5199     //-----------------------------------------------------------
5200     // IUnknown
5201     //-----------------------------------------------------------
5202
5203     ULONG STDMETHODCALLTYPE AddRef()
5204     {
5205         return (BaseAddRef());
5206     }
5207     ULONG STDMETHODCALLTYPE Release()
5208     {
5209         return (BaseRelease());
5210     }
5211     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5212
5213     //-----------------------------------------------------------
5214     // ICorDebugEnum
5215     //-----------------------------------------------------------
5216
5217     COM_METHOD Skip(ULONG celt);
5218     COM_METHOD Reset();
5219     COM_METHOD Clone(ICorDebugEnum **ppEnum);
5220     COM_METHOD GetCount(ULONG *pcelt);
5221
5222     //-----------------------------------------------------------
5223     // ICorDebugTypeEnum
5224     //-----------------------------------------------------------
5225
5226     COM_METHOD Next(ULONG celt, ICorDebugType *Types[], ULONG *pceltFetched);
5227
5228 private:
5229     // Private constructor, only partially initializes the object.
5230     // Clients should use the 'Build' factory method to create an instance of this class.
5231     CordbTypeEnum( CordbAppDomain * pAppDomain, NeuterList * pNeuterList );
5232     template<class T> static CordbTypeEnum* BuildImpl(CordbAppDomain * pAppDomain, NeuterList * pNeuterList, unsigned int cTypars, T* ppTypars );
5233
5234     // Owning object.
5235     CordbAppDomain * m_pAppDomain;
5236
5237     // Array of Types. We own the array, and share refs to the types.
5238     // @todo- since these are guaranteed to be kept alive as long as we're not neutered,
5239     // we don't need to keep refs to them.
5240     RSSmartPtr<CordbType> * m_ppTypars;
5241     UINT   m_iCurrent;
5242     UINT   m_iMax;
5243 };
5244
5245 /* ------------------------------------------------------------------------- *
5246  * Code enumerator class
5247  * ------------------------------------------------------------------------- */
5248
5249 class CordbCodeEnum : public CordbBase, public ICorDebugCodeEnum
5250 {
5251 public:
5252     CordbCodeEnum(unsigned int cCode, RSSmartPtr<CordbCode> * ppCode);
5253     virtual ~CordbCodeEnum() ;
5254
5255
5256 #ifdef _DEBUG
5257     virtual const char * DbgGetName() { return "CordbCodeEnum"; }
5258 #endif
5259
5260
5261     //-----------------------------------------------------------
5262     // IUnknown
5263     //-----------------------------------------------------------
5264
5265     ULONG STDMETHODCALLTYPE AddRef()
5266     {
5267         return (BaseAddRef());
5268     }
5269     ULONG STDMETHODCALLTYPE Release()
5270     {
5271         return (BaseRelease());
5272     }
5273     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5274
5275     //-----------------------------------------------------------
5276     // ICorDebugEnum
5277     //-----------------------------------------------------------
5278
5279     COM_METHOD Skip(ULONG celt);
5280     COM_METHOD Reset();
5281     COM_METHOD Clone(ICorDebugEnum **ppEnum);
5282     COM_METHOD GetCount(ULONG *pcelt);
5283
5284     //-----------------------------------------------------------
5285     // ICorDebugCodeEnum
5286     //-----------------------------------------------------------
5287
5288     COM_METHOD Next(ULONG celt, ICorDebugCode *Codes[], ULONG *pceltFetched);
5289
5290 private:
5291     // Ptr to an array of CordbCode*
5292     // We own the array.
5293     RSSmartPtr<CordbCode> * m_ppCodes;
5294     UINT   m_iCurrent;
5295     UINT   m_iMax;
5296 };
5297
5298
5299
5300
5301
5302 typedef CUnorderedArray<CordbCode*,11> UnorderedCodeArray;
5303 //<TODO>@todo port: different SIZE_T size/</TODO>
5304 const int DMI_VERSION_INVALID = 0;
5305 const int DMI_VERSION_MOST_RECENTLY_JITTED = 1;
5306 const int DMI_VERSION_MOST_RECENTLY_EnCED = 2;
5307
5308
5309 /* ------------------------------------------------------------------------- *
5310  * Function class
5311  *
5312  * @review .  The CordbFunction class now keeps a multiple MethodDescInfo
5313  * structures in a hash table indexed by tokens provided by the left-side.
5314  * In 99.9% of cases this hash table will only contain one entry - we only
5315  * use a hashtable to cover the case where we have multiple JITtings of
5316  * a single version of a function, in particular multiple JITtings of generic
5317  * code under different instantiations. This will increase space usage.
5318  * The way around it is to store one CordbNativeCode in-line in the CordbFunction
5319  * class, or at least store one such pointer so no hash table will normally
5320  * be needed.  This is similar to other cases, e.g. the hash table in
5321  * CordbClass used to indicate different CordbTypes made from that class -
5322  * again in the normal case these tables will only contain one element.
5323  *
5324  * However, for the moment I've focused on correctness and we can minimize
5325  * this space usage in due course.
5326  * ------------------------------------------------------------------------- */
5327
5328 const BOOL bNativeCode = FALSE;
5329 const BOOL bILCode = TRUE;
5330
5331 //
5332 // Each E&C version gets its own function object. So the IL that a function
5333 // is associated w/ does not change.
5334 // B/C of generics, a single IL function may get jitted multiple times and
5335 // be associated w/ multiple native code blobs (CordbNativeCode).
5336 //
5337 class CordbFunction : public CordbBase, public ICorDebugFunction, public ICorDebugFunction2, public ICorDebugFunction3
5338 {
5339 public:
5340     //-----------------------------------------------------------
5341     // Create from scope and member objects.
5342     //-----------------------------------------------------------
5343     CordbFunction(CordbModule * m,
5344                   mdMethodDef token,
5345                   SIZE_T enCVersion);
5346     virtual ~CordbFunction();
5347     virtual void Neuter();
5348
5349
5350
5351 #ifdef _DEBUG
5352     virtual const char * DbgGetName() { return "CordbFunction"; }
5353 #endif
5354
5355
5356     //-----------------------------------------------------------
5357     // IUnknown
5358     //-----------------------------------------------------------
5359
5360     ULONG STDMETHODCALLTYPE AddRef()
5361     {
5362         return (BaseAddRef());
5363     }
5364     ULONG STDMETHODCALLTYPE Release()
5365     {
5366         return (BaseRelease());
5367     }
5368     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5369
5370     //-----------------------------------------------------------
5371     // ICorDebugFunction
5372     //-----------------------------------------------------------
5373     COM_METHOD GetModule(ICorDebugModule **pModule);
5374     COM_METHOD GetClass(ICorDebugClass **ppClass);
5375     COM_METHOD GetToken(mdMethodDef *pMemberDef);
5376     COM_METHOD GetILCode(ICorDebugCode **ppCode);
5377     COM_METHOD GetNativeCode(ICorDebugCode **ppCode);
5378     COM_METHOD CreateBreakpoint(ICorDebugFunctionBreakpoint **ppBreakpoint);
5379     COM_METHOD GetLocalVarSigToken(mdSignature *pmdSig);
5380     COM_METHOD GetCurrentVersionNumber(ULONG32 *pnCurrentVersion);
5381
5382     //-----------------------------------------------------------
5383     // ICorDebugFunction2
5384     //-----------------------------------------------------------
5385     COM_METHOD SetJMCStatus(BOOL fIsUserCode);
5386     COM_METHOD GetJMCStatus(BOOL * pfIsUserCode);
5387     COM_METHOD EnumerateNativeCode(ICorDebugCodeEnum **ppCodeEnum) { return E_NOTIMPL; }
5388     COM_METHOD GetVersionNumber(ULONG32 *pnCurrentVersion);
5389
5390     //-----------------------------------------------------------
5391     // ICorDebugFunction3
5392     //-----------------------------------------------------------
5393     COM_METHOD GetActiveReJitRequestILCode(ICorDebugILCode **ppReJitedILCode);
5394
5395     //-----------------------------------------------------------
5396     // Internal members
5397     //-----------------------------------------------------------
5398 protected:
5399     // Returns the function's ILCode and SigToken 
5400     HRESULT GetILCodeAndSigToken();
5401
5402     // Get the metadata token for the class to which a function belongs. 
5403     mdTypeDef InitParentClassOfFunctionHelper(mdToken funcMetaDataToken);
5404
5405     // Get information about one of the native code blobs for this function
5406     HRESULT InitNativeCodeInfo();
5407
5408 public:
5409
5410     // Get the class to which a given function belongs
5411     HRESULT InitParentClassOfFunction();
5412
5413     void NotifyCodeCreated(CordbNativeCode* nativeCode);
5414
5415     HRESULT GetSig(SigParser *pMethodSigParser,
5416                    ULONG *pFunctionArgCount,
5417                    BOOL *pFunctionIsStatic);
5418
5419     HRESULT GetArgumentType(DWORD dwIndex, const Instantiation * pInst, CordbType ** ppResultType);
5420
5421
5422     //-----------------------------------------------------------
5423     // Internal routines
5424     //-----------------------------------------------------------
5425
5426     // Get the existing IL code object
5427     HRESULT GetILCode(CordbILCode ** ppCode);
5428
5429     // Finds or creates an ILCode for a given rejit request
5430     HRESULT LookupOrCreateReJitILCode(VMPTR_SharedReJitInfo vmSharedRejitInfo,
5431                                       CordbReJitILCode** ppILCode);
5432
5433
5434 #ifdef EnC_SUPPORTED
5435     void MakeOld();
5436 #endif
5437
5438     //-----------------------------------------------------------
5439     // Accessors
5440     //-----------------------------------------------------------
5441
5442     // Get the AppDomain that this function lives in.
5443     CordbAppDomain * GetAppDomain()
5444     {
5445         return (m_pModule->GetAppDomain());
5446     }
5447
5448     // Get the CordbModule that this Function lives in. 
5449     CordbModule * GetModule()
5450     {
5451         return m_pModule;
5452     }
5453
5454     // Get the CordbClass this of which this function is a member
5455     CordbClass * GetClass()
5456     {
5457         return m_pClass;
5458     }
5459
5460     // Get the IL code blob corresponding to this function
5461     CordbILCode * GetILCode()
5462     {
5463         return m_pILCode;
5464     }
5465
5466     // Get metadata token for this function
5467     mdMethodDef GetMetadataToken()
5468     {
5469         return m_MDToken;
5470     }
5471
5472     SIZE_T GetEnCVersionNumber()
5473     {
5474         return m_dwEnCVersionNumber;
5475     }
5476
5477     CordbFunction * GetPrevVersion()
5478     {
5479         return m_pPrevVersion;
5480     }
5481
5482     void SetPrevVersion(CordbFunction * prevVersion)
5483     {
5484         m_pPrevVersion.Assign(prevVersion);
5485     }
5486
5487     typedef enum {kNativeOnly, kHasIL, kUnknownImpl} ImplementationKind;
5488     ImplementationKind IsNativeImpl()
5489     {
5490         return (m_fIsNativeImpl);
5491     }
5492
5493     // determine whether we have a native-only implementation
5494     void InitNativeImpl();
5495
5496
5497     //-----------------------------------------------------------
5498     // Data members
5499     //-----------------------------------------------------------
5500
5501 private:
5502     // The module that this Function is contained in. It maintains a strong reference to this object
5503     // and will neuter this object.
5504     CordbModule *            m_pModule;
5505
5506     // The Class that this function is contained in. 
5507     CordbClass *             m_pClass;
5508
5509     // We only have 1 IL blob associated with a given Function object.
5510     RSSmartPtr<CordbILCode>  m_pILCode;
5511
5512
5513     // Generics allow a single IL method to be instantiated to multiple native
5514     // code blobs. So CordbFunction : CordbNativeCode is 1:n.
5515     // This pointer is to arbitrary one of those n code bodies.
5516     // Someday we may need to get access to all N of them but not today
5517     RSSmartPtr<CordbNativeCode> m_nativeCode;
5518
5519     // Metadata Token for the IL function. Scoped to m_module.
5520     mdMethodDef              m_MDToken;
5521
5522     // EnC version number of this instance
5523     SIZE_T                   m_dwEnCVersionNumber; 
5524
5525     // link to previous version of this function
5526     RSSmartPtr<CordbFunction> m_pPrevVersion; 
5527
5528     // Is the function implemented natively in the runtime?? (eg, it has no IL, may be an Ecall/fcall)
5529     ImplementationKind       m_fIsNativeImpl; 
5530
5531     // True if method signature (argument) values are cached.
5532     BOOL                     m_fCachedMethodValuesValid;
5533
5534     // Cached SigParser for this Function's argument signature.
5535     // Only valid if m_fCachedMethodValuesValid is set.
5536     SigParser                m_methodSigParserCached;
5537
5538     // Cached Count of arguments in the argument signature.
5539     // Only valid if m_fCachedMethodValuesValid is set.
5540     ULONG                    m_argCountCached;
5541
5542     // Cached boolean if method is static or instance (part of the argument signature).
5543     // Only valid if m_fCachedMethodValuesValid is set.
5544     BOOL                     m_fIsStaticCached;
5545
5546     // A collection, indexed by VMPTR_SharedReJitInfo, of IL code for rejit requests
5547     // The collection is filled lazily by LookupOrCreateReJitILCode
5548     CordbSafeHashTable<CordbReJitILCode> m_reJitILCodes;
5549 };
5550
5551 //-----------------------------------------------------------------------------
5552 // class CordbCode
5553 // Represents either IL or Native code blobs associated with a function.
5554 //
5555 // See the comments at the ICorDebugCode definition for invariants about Code objects.
5556 // 
5557 //-----------------------------------------------------------------------------
5558 class CordbCode : public CordbBase, public ICorDebugCode
5559 {
5560 protected:
5561     CordbCode(CordbFunction * pFunction, UINT_PTR id, SIZE_T encVersion, BOOL fIsIL);
5562
5563 public:
5564     virtual ~CordbCode();
5565     virtual void Neuter();
5566
5567 #ifdef _DEBUG
5568     virtual const char * DbgGetName() = 0;
5569 #endif
5570
5571
5572     //-----------------------------------------------------------
5573     // IUnknown
5574     //-----------------------------------------------------------
5575
5576     ULONG STDMETHODCALLTYPE AddRef()
5577     {
5578         return (BaseAddRef());
5579     }
5580     ULONG STDMETHODCALLTYPE Release()
5581     {
5582         return (BaseRelease());
5583     }
5584     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5585
5586     //-----------------------------------------------------------
5587     // ICorDebugCode
5588     //-----------------------------------------------------------
5589
5590     COM_METHOD IsIL(BOOL * pbIL);
5591     COM_METHOD GetFunction(ICorDebugFunction ** ppFunction);
5592     COM_METHOD GetAddress(CORDB_ADDRESS * pStart) = 0;
5593     COM_METHOD GetSize(ULONG32 * pcBytes);
5594     COM_METHOD CreateBreakpoint(ULONG32 offset,
5595                                 ICorDebugFunctionBreakpoint ** ppBreakpoint);
5596     COM_METHOD GetCode(ULONG32 startOffset, ULONG32 endOffset,
5597                        ULONG32 cBufferAlloc,
5598                        BYTE buffer[],
5599                        ULONG32 * pcBufferSize);
5600     COM_METHOD GetVersionNumber( ULONG32 * nVersion);
5601     COM_METHOD GetILToNativeMapping(ULONG32 cMap,
5602                                     ULONG32 * pcMap,
5603                                     COR_DEBUG_IL_TO_NATIVE_MAP map[]) = 0;
5604     COM_METHOD GetEnCRemapSequencePoints(ULONG32 cMap,
5605                                          ULONG32 * pcMap,
5606                                          ULONG32 offsets[]);
5607
5608     //-----------------------------------------------------------
5609     // Accessors and convenience routines
5610     //-----------------------------------------------------------
5611
5612     // get the CordbFunction instance for this code object
5613     CordbFunction * GetFunction();
5614
5615     // get the actual code bytes for this function
5616     virtual HRESULT ReadCodeBytes() = 0;
5617
5618     // get the size in bytes of this function
5619     virtual ULONG32 GetSize() = 0;
5620
5621
5622     // get the metadata token for this code object
5623     mdMethodDef GetMetadataToken()
5624     {
5625         _ASSERTE(m_pFunction != NULL);
5626         return (m_pFunction->GetMetadataToken());
5627     }
5628  
5629     // get the module this code object belongs to
5630     CordbModule * GetModule()
5631     {
5632         _ASSERTE(m_pFunction != NULL);
5633         return (m_pFunction->GetModule());
5634     }
5635
5636     // get the function signature for this code blob or throw on failure
5637     void GetSig(SigParser *pMethodSigParser,
5638                 ULONG *pFunctionArgCount,
5639                 BOOL *pFunctionIsStatic)
5640     {
5641         _ASSERTE(m_pFunction != NULL);
5642         IfFailThrow(m_pFunction->GetSig(pMethodSigParser, pFunctionArgCount, pFunctionIsStatic));
5643     }
5644     
5645     // get the class to which this code blob belongs
5646     CordbClass * GetClass()
5647     {
5648         _ASSERTE(m_pFunction != NULL);
5649         return (m_pFunction->GetClass());
5650     }
5651
5652     // Quick helper to get the AppDomain that this code object lives in. 
5653     CordbAppDomain *GetAppDomain()
5654     {
5655         _ASSERTE(m_pFunction != NULL);
5656         return (m_pFunction->GetAppDomain());
5657     }
5658
5659     // Get the EnC version of this blob
5660     SIZE_T GetVersion() { return m_nVersion; };
5661
5662     // Return true if this is an IL code blob. Else return false.
5663     BOOL IsIL() { return m_fIsIL; }
5664
5665     // convert to CordbNativeCode as long as m_fIsIl is false.
5666     CordbNativeCode * AsNativeCode()
5667     {
5668         _ASSERTE(m_fIsIL == FALSE);
5669         return reinterpret_cast<CordbNativeCode *>(this);
5670     }
5671
5672     // convert to CordbILCode as long as m_fIsIl is true.
5673     CordbILCode * AsILCode()
5674     {
5675         _ASSERTE(m_fIsIL == TRUE);
5676         return reinterpret_cast<CordbILCode *>(this);
5677     }
5678
5679     //-----------------------------------------------------------
5680     // Data members
5681     //-----------------------------------------------------------
5682
5683 private:
5684     UINT m_fIsIL : 1;
5685
5686     // EnC version number.
5687     SIZE_T                 m_nVersion;
5688
5689 protected:
5690     // Our local copy of the code. It will be GetSize() bytes long.
5691     BYTE *                 m_rgbCode; // will be NULL if we can't fit it into memory
5692
5693     UINT                   m_continueCounterLastSync;
5694
5695     // Owning Function associated with this code.
5696     CordbFunction *        m_pFunction;
5697 }; //class CordbCode
5698
5699
5700
5701
5702
5703 /* ------------------------------------------------------------------------- *
5704 * CordbILCode class
5705 * This class represents an IL code blob for a particular EnC version. Thus it is 
5706 * 1:1 with a given instantiation of CordbFunction. Provided functionality includes
5707 * methods to get the starting address and size of an IL code blob and to read
5708 * the actual bytes of IL into a buffer. 
5709  * ------------------------------------------------------------------------- */
5710
5711 class CordbILCode : public CordbCode
5712 {
5713 public:
5714     // Initialize a new CordbILCode instance
5715     CordbILCode(CordbFunction *pFunction, TargetBuffer codeRegionInfo, SIZE_T nVersion, mdSignature localVarSigToken, UINT_PTR id = 0);
5716
5717 #ifdef _DEBUG
5718     const char * DbgGetName() { return "CordbILCode"; };
5719 #endif // _DEBUG
5720
5721     COM_METHOD GetAddress(CORDB_ADDRESS * pStart);
5722     COM_METHOD GetILToNativeMapping(ULONG32 cMap,
5723                                     ULONG32 * pcMap,
5724                                     COR_DEBUG_IL_TO_NATIVE_MAP map[]);
5725     // Quick helper for internal access to: GetAddress(CORDB_ADDRESS *pStart);
5726     CORDB_ADDRESS GetAddress() { return m_codeRegionInfo.pAddress; }
5727
5728     // get total size of the IL code
5729     ULONG32 GetSize() { return m_codeRegionInfo.cbSize; }
5730
5731 #ifdef EnC_SUPPORTED
5732     void MakeOld();
5733 #endif // EnC_SUPPORTED
5734
5735     HRESULT GetLocalVarSig(SigParser *pLocalsSigParser, ULONG *pLocalVarCount);
5736     HRESULT GetLocalVariableType(DWORD dwIndex, const Instantiation * pInst, CordbType ** ppResultType);
5737     mdSignature GetLocalVarSigToken();
5738
5739 private:
5740     // Read the actual bytes of IL code into the data member m_rgbCode.
5741     // Helper routine for GetCode
5742     HRESULT ReadCodeBytes();
5743
5744     //-----------------------------------------------------------
5745     // Data members
5746     //-----------------------------------------------------------
5747
5748 private:
5749 #ifdef EnC_SUPPORTED
5750     UINT m_fIsOld : 1;           // marks this instance as an old EnC version
5751     bool m_encBreakpointsApplied;
5752 #endif
5753
5754     // derived types can init this
5755 protected:
5756     TargetBuffer m_codeRegionInfo;  // stores the starting address and size of the 
5757                                     // IL code blob
5758
5759     // Metadata token for local's signature.    
5760     mdSignature m_localVarSigToken;
5761
5762 }; // class CordbILCode
5763
5764 /* ------------------------------------------------------------------------- *
5765 * CordbReJitILCode class
5766 * This class represents an IL code blob for a particular EnC version and
5767 * rejitID. Thus it is 1:N with a given instantiation of CordbFunction.
5768 * ------------------------------------------------------------------------- */
5769
5770 class CordbReJitILCode : public CordbILCode, public ICorDebugILCode, public ICorDebugILCode2
5771 {
5772 public:
5773     // Initialize a new CordbILCode instance
5774     CordbReJitILCode(CordbFunction *pFunction, SIZE_T encVersion, VMPTR_SharedReJitInfo vmSharedReJitInfo);
5775
5776     //-----------------------------------------------------------
5777     // IUnknown
5778     //-----------------------------------------------------------
5779     ULONG STDMETHODCALLTYPE AddRef();
5780     ULONG STDMETHODCALLTYPE Release();
5781     COM_METHOD QueryInterface(REFIID riid, void** ppInterface);
5782
5783
5784     //-----------------------------------------------------------
5785     // ICorDebugILCode
5786     //-----------------------------------------------------------
5787     COM_METHOD GetEHClauses(ULONG32 cClauses, ULONG32 * pcClauses, CorDebugEHClause clauses[]);
5788
5789
5790     //-----------------------------------------------------------
5791     // ICorDebugILCode2
5792     //-----------------------------------------------------------
5793     COM_METHOD GetLocalVarSigToken(mdSignature *pmdSig);
5794     COM_METHOD GetInstrumentedILMap(ULONG32 cMap, ULONG32 *pcMap, COR_IL_MAP map[]);
5795
5796 private:
5797     HRESULT Init(DacSharedReJitInfo* pSharedReJitInfo);
5798
5799 private:
5800     ULONG32 m_cClauses;
5801     NewArrayHolder<CorDebugEHClause> m_pClauses;
5802     ULONG32 m_cbLocalIL;
5803     NewArrayHolder<BYTE> m_pLocalIL;
5804     ULONG32 m_cILMap;
5805     NewArrayHolder<COR_IL_MAP> m_pILMap;
5806 };
5807
5808 /* ------------------------------------------------------------------------- *
5809  * CordbNativeCode class. These correspond to MethodDesc's on the left-side.
5810  * There may or may not be a DebuggerJitInfo associated with the MethodDesc.
5811  * At most one CordbNativeCode is created for each native code compilation of each method
5812  * that is seen by the right-side.  Note that if each method were JITted only once
5813  * then this information could go in CordbFunction, however generics allow
5814  * methods to be compiled more than once.
5815  *
5816  * The purpose of this class is to encapsulate details about a blob of jitted/ngen'ed
5817  * code, including an optional set of mappings from IL to offsets in the native Code.
5818  * ------------------------------------------------------------------------- */
5819
5820 class CordbNativeCode : public CordbCode,
5821                         public ICorDebugCode2,
5822                         public ICorDebugCode3,
5823                         public ICorDebugCode4
5824 {
5825 public:
5826     CordbNativeCode(CordbFunction * pFunction, 
5827                     const NativeCodeFunctionData * pJitData, 
5828                     BOOL fIsInstantiatedGeneric);
5829 #ifdef _DEBUG
5830     const char * DbgGetName() { return "CordbNativeCode"; };
5831 #endif // _DEBUG
5832
5833     ULONG STDMETHODCALLTYPE AddRef()
5834     {
5835         return (BaseAddRef());
5836     }
5837     ULONG STDMETHODCALLTYPE Release()
5838     {
5839         return (BaseRelease());
5840     }
5841     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5842
5843     //-----------------------------------------------------------
5844     // ICorDebugCode
5845     //-----------------------------------------------------------
5846     COM_METHOD GetAddress(CORDB_ADDRESS * pStart);
5847     COM_METHOD GetILToNativeMapping(ULONG32 cMap,
5848                                     ULONG32 * pcMap,
5849                                     COR_DEBUG_IL_TO_NATIVE_MAP map[]);
5850     //-----------------------------------------------------------
5851     // ICorDebugCode2
5852     //-----------------------------------------------------------
5853     COM_METHOD GetCodeChunks(ULONG32 cbufSize, ULONG32 * pcnumChunks, CodeChunkInfo chunks[]);
5854
5855     COM_METHOD GetCompilerFlags(DWORD * pdwFlags);
5856
5857     //-----------------------------------------------------------
5858     // ICorDebugCode3
5859     //-----------------------------------------------------------
5860     COM_METHOD GetReturnValueLiveOffset(ULONG32 ILoffset, ULONG32 bufferSize, ULONG32 *pFetched, ULONG32 *pOffsets);
5861     
5862
5863     //-----------------------------------------------------------
5864     // ICorDebugCode4
5865     //-----------------------------------------------------------
5866     COM_METHOD EnumerateVariableHomes(ICorDebugVariableHomeEnum **ppEnum);
5867     
5868     //-----------------------------------------------------------
5869     // Internal members
5870     //-----------------------------------------------------------
5871
5872     HRESULT ILVariableToNative(DWORD dwIndex,
5873                                SIZE_T ip,
5874                                const ICorDebugInfo::NativeVarInfo ** ppNativeInfo);
5875     void LoadNativeInfo();
5876
5877     //-----------------------------------------------------------
5878     // Accessors and convenience routines
5879     //-----------------------------------------------------------
5880
5881     // get the argument type for a generic 
5882     void GetArgumentType(DWORD                 dwIndex,
5883                          const Instantiation * pInst,
5884                          CordbType **          ppResultType)
5885     {
5886         CordbFunction * pFunction = GetFunction();
5887         _ASSERTE(pFunction != NULL);
5888         IfFailThrow(pFunction->GetArgumentType(dwIndex, pInst, ppResultType));
5889     }
5890
5891     // Quick helper for internall access to: GetAddress(CORDB_ADDRESS *pStart);
5892     CORDB_ADDRESS GetAddress() { return m_rgCodeRegions[kHot].pAddress; };
5893
5894     VMPTR_MethodDesc GetVMNativeCodeMethodDescToken() { return m_vmNativeCodeMethodDescToken; };
5895
5896     // Worker function for GetReturnValueLiveOffset.
5897     HRESULT GetReturnValueLiveOffsetImpl(Instantiation *currentInstantiation, ULONG32 ILoffset, ULONG32 bufferSize, ULONG32 *pFetched, ULONG32 *pOffsets);
5898
5899     // get total size of the code including both hot and cold regions
5900     ULONG32 GetSize();
5901
5902     // get the size of the cold region(s) only
5903     ULONG32 GetColdSize();
5904
5905     // Return true if the Code is split into hot + cold regions.
5906     bool HasColdRegion() { return m_rgCodeRegions[kCold].pAddress != NULL; }
5907
5908     // Get the number of fixed arguments for this function (the "this" 
5909     // but not varargs)
5910     unsigned int GetFixedArgCount()
5911     {
5912         return m_nativeVarData.GetFixedArgCount();
5913     }
5914
5915     // Get the number of all arguments for this function 
5916     // ("this" pointer, fixed args and varargs)
5917     ULONG32 GetAllArgsCount()
5918     {
5919         return m_nativeVarData.GetAllArgsCount();
5920     }
5921
5922     void SetAllArgsCount(ULONG32 count)
5923     {
5924         m_nativeVarData.SetAllArgsCount(count);
5925     }
5926
5927     // Determine whether this is an instantiation of a generic function
5928     BOOL IsInstantiatedGeneric()
5929     {
5930         return m_fIsInstantiatedGeneric != 0;
5931     }
5932
5933     // Determine whether we have initialized the native variable and 
5934     // sequence point offsets
5935     BOOL IsNativeCodeValid ()
5936     {
5937         return ((m_nativeVarData.IsInitialized() != 0) && 
5938                (m_sequencePoints.IsInitialized() != 0));
5939     }
5940
5941     SequencePoints * GetSequencePoints()
5942     {
5943         return &m_sequencePoints;
5944     }
5945
5946
5947     // Given an ILOffset in the current function, return the class token and function token of the IL call target at that
5948     // location.  Also fill "methodSig" with the method's signature and "genericSig" with the method's generic signature.
5949     HRESULT GetCallSignature(ULONG32 ILOffset, mdToken *pClass, mdToken *pMDFunction, SigParser &methodSig, SigParser &genericSig);
5950
5951     // Moves a method signature from the start of the signature to the location of the return value (passing out the
5952     // number of generic parameters in the method).
5953     static HRESULT SkipToReturn(SigParser &parser, ULONG *genArgCount = 0);
5954
5955 private:
5956     // Read the actual bytes of native code into the data member m_rgbCode.
5957     // Helper routine for GetCode
5958     HRESULT ReadCodeBytes();
5959
5960     // Returns a failure HRESULT if we cannot handle the return value of the given
5961     // methodref, methoddef, or methodspec token, otherwise S_OK.  Does NOT return S_FALSE;
5962     HRESULT EnsureReturnValueAllowed(Instantiation *currentInstantiation, mdToken targetClass, SigParser &parser, SigParser &methodGenerics);
5963     HRESULT EnsureReturnValueAllowedWorker(Instantiation *currentInstantiation, mdToken targetClass, SigParser &parser, SigParser &methodGenerics, ULONG genCount);
5964     
5965     // Grabs the appropriate signature parser for a methodref, methoddef, methodspec.
5966     HRESULT GetSigParserFromFunction(mdToken mdFunction, mdToken *pClass, SigParser &methodSig, SigParser &genericSig);
5967
5968     int GetCallInstructionLength(BYTE *buffer, ULONG32 len);
5969
5970     //-----------------------------------------------------------
5971     // Data members
5972     //-----------------------------------------------------------
5973 private:
5974     // offset of the beginning of the last sequence point in the sequence point map
5975     SIZE_T                   m_lastIL;
5976
5977     // start address(es) and size(s) of hot and cold regions
5978     TargetBuffer             m_rgCodeRegions[MAX_REGIONS];
5979
5980     // LS data structure--method desc for this instantiation.
5981     VMPTR_MethodDesc         m_vmNativeCodeMethodDescToken;
5982
5983     bool                     m_fCodeAvailable;          // true iff the code has been jitted but not pitched
5984
5985     bool                     m_fIsInstantiatedGeneric;  // true iff this is an instantiated generic
5986
5987     // information in the following two classes tracks native offsets and is initialized on demand. 
5988
5989     // location and ID information for local variables. See code:NativeVarData for details.
5990     NativeVarData            m_nativeVarData;
5991
5992     // mapping between IL and native code sequence points. 
5993     SequencePoints           m_sequencePoints;
5994
5995 }; //class CordbNativeCode
5996
5997 //---------------------------------------------------------------------------------------
5998 //
5999 // GetActiveInternalFramesData is used to enumerate internal frames on a specific thread.
6000 // It is used in conjunction with code:CordbThread::GetActiveInternalFramesCallback.
6001 // We store each internal frame in ppInternalFrames as we enumerate them.
6002 //
6003
6004 struct GetActiveInternalFramesData
6005 {
6006 public:
6007     // the thread we are walking
6008     CordbThread * pThis;
6009
6010     // an array to store the internal frames
6011     RSPtrArray<CordbInternalFrame> pInternalFrames;
6012
6013     // next element in the array to be filled
6014     ULONG32 uIndex;
6015 };
6016
6017
6018 /* ------------------------------------------------------------------------- *
6019  * Thread classes
6020  * ------------------------------------------------------------------------- */
6021
6022 class CordbThread : public CordbBase, public ICorDebugThread,
6023                                       public ICorDebugThread2,
6024                                       public ICorDebugThread3,
6025                                       public ICorDebugThread4
6026 {
6027 public:
6028     CordbThread(CordbProcess * pProcess, VMPTR_Thread);
6029
6030     virtual ~CordbThread();
6031     virtual void Neuter();
6032
6033     using CordbBase::GetProcess;
6034     
6035 #ifdef _DEBUG
6036     virtual const char * DbgGetName() { return "CordbThread"; }
6037 #endif
6038
6039     //-----------------------------------------------------------
6040     // IUnknown
6041     //-----------------------------------------------------------
6042
6043     ULONG STDMETHODCALLTYPE AddRef()
6044     {
6045         // there's an external add ref from within RS in CordbEnumFilter
6046         return (BaseAddRef());
6047     }
6048     ULONG STDMETHODCALLTYPE Release()
6049     {
6050         return (BaseRelease());
6051     }
6052     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6053
6054     //-----------------------------------------------------------
6055     // ICorDebugThread
6056     //-----------------------------------------------------------
6057
6058     COM_METHOD GetProcess(ICorDebugProcess **ppProcess);
6059     COM_METHOD GetID(DWORD *pdwThreadId);
6060     COM_METHOD GetHandle(HANDLE * phThreadHandle);
6061     COM_METHOD GetAppDomain(ICorDebugAppDomain **ppAppDomain);
6062     COM_METHOD SetDebugState(CorDebugThreadState state);
6063     COM_METHOD GetDebugState(CorDebugThreadState *pState);
6064     COM_METHOD GetUserState(CorDebugUserState *pState);
6065     COM_METHOD GetCurrentException(ICorDebugValue ** ppExceptionObject);
6066     COM_METHOD ClearCurrentException();
6067     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper);
6068     COM_METHOD EnumerateChains(ICorDebugChainEnum **ppChains);
6069     COM_METHOD GetActiveChain(ICorDebugChain **ppChain);
6070     COM_METHOD GetActiveFrame(ICorDebugFrame **ppFrame);
6071     COM_METHOD GetRegisterSet(ICorDebugRegisterSet **ppRegisters);
6072     COM_METHOD CreateEval(ICorDebugEval **ppEval);
6073     COM_METHOD GetObject(ICorDebugValue ** ppObject);
6074
6075     // ICorDebugThread2
6076     COM_METHOD GetConnectionID(CONNID * pConnectionID);
6077     COM_METHOD GetTaskID(TASKID * pTaskID);
6078     COM_METHOD GetVolatileOSThreadID(DWORD * pdwTID);
6079     COM_METHOD GetActiveFunctions(ULONG32 cFunctions, ULONG32 * pcFunctions, COR_ACTIVE_FUNCTION pFunctions[]);
6080     // Intercept the current exception at the specified frame.  pFrame must be a valid ICDFrame, possibly from
6081     // a previous stackwalk.
6082     COM_METHOD InterceptCurrentException(ICorDebugFrame * pFrame);
6083
6084
6085
6086     // ICorDebugThread3
6087     COM_METHOD CreateStackWalk(ICorDebugStackWalk **ppStackWalk);
6088
6089     COM_METHOD GetActiveInternalFrames(ULONG32 cInternalFrames,
6090                                        ULONG32 * pcInternalFrames,
6091                                        ICorDebugInternalFrame2 * ppInternalFrames[]);
6092
6093     // ICorDebugThread4
6094     COM_METHOD HasUnhandledException();
6095
6096     COM_METHOD GetBlockingObjects(ICorDebugBlockingObjectEnum **ppBlockingObjectEnum);
6097
6098     // Gets the current CustomNotification object from the thread or NULL if no such object exists 
6099     COM_METHOD GetCurrentCustomDebuggerNotification(ICorDebugValue ** ppNotificationObject);
6100     //-----------------------------------------------------------
6101     // Internal members
6102     //-----------------------------------------------------------
6103
6104     // callback used to enumerate the internal frames on a thread 
6105     static void GetActiveInternalFramesCallback(const DebuggerIPCE_STRData * pFrameData,
6106                                                 void *                 pUserData);
6107
6108     CorDebugUserState GetUserState();
6109
6110     // Given a FramePointer, find the matching CordbFrame.
6111     HRESULT FindFrame(ICorDebugFrame ** ppFrame, FramePointer fp);
6112
6113     // Get the task ID for this thread.
6114     TASKID GetTaskID();
6115
6116     void RefreshStack();
6117     void CleanupStack();
6118     void MarkStackFramesDirty();
6119
6120 #if !defined(DBG_TARGET_ARM) // @ARMTODO
6121
6122 #if defined(DBG_TARGET_X86)
6123     // Converts the values in the floating point register area of the context to real number values.
6124     void Get32bitFPRegisters(CONTEXT * pContext);
6125
6126 #elif defined(DBG_TARGET_AMD64) ||  defined(DBG_TARGET_ARM64)
6127     // Converts the values in the floating point register area of the context to real number values.
6128     void Get64bitFPRegisters(FPRegister64 * rgContextFPRegisters, int start, int nRegisters);
6129 #endif // DBG_TARGET_X86
6130
6131    // Initializes the float state members of this instance of CordbThread. This function gets the context and
6132    // converts the floating point values from their context representation to real number values.    
6133    void LoadFloatState();
6134
6135 #endif //!DBG_TARGET_ARM @ARMTODO
6136
6137     HRESULT SetIP(  bool fCanSetIPOnly,
6138                     CordbNativeCode * pNativeCode,
6139                     SIZE_T offset,
6140                     bool fIsIL );
6141
6142     // Tells the LS to remap to the latest version of the function
6143     HRESULT SetRemapIP(SIZE_T offset);
6144
6145     // Ask the left-side for the current (up-to-date) AppDomain of this thread's IP.
6146     // This should be preferred over using the cached value from GetAppDomain.
6147     HRESULT GetCurrentAppDomain(CordbAppDomain ** ppAppDomain);
6148
6149     //-----------------------------------------------------------
6150     // Convenience routines
6151     //-----------------------------------------------------------
6152
6153     // The last domain from which a debug event for this thread was sent.
6154     // This usually (but not always) the domain the thread is currently executing in.
6155     // Since this is a cache, it may sometimes be out-of-date.  I believe all current
6156     // usage of this is OK (we pass AppDomains around a lot without really using them),
6157     // but no new code should rely on this value.
6158     // TODO: eliminate this and the m_pAppDomain field entirely
6159     CordbAppDomain *GetAppDomain()
6160     {
6161         return (m_pAppDomain);
6162     }
6163
6164     DWORD GetVolatileOSThreadID();
6165
6166     //////////////////////////////////////////////////////////////////////////
6167     //
6168     // Get Context
6169     //
6170     //      <TODO>TODO: Since Thread will share the memory with RegisterSets, how
6171     //      do we know that the RegisterSets have relinquished all pointers
6172     //      to the m_pContext structure?</TODO>
6173     //
6174     // Returns: NULL if the thread's CONTEXT structure couldn't be obtained
6175     //   A pointer to the CONTEXT otherwise.
6176     //
6177     //
6178     //////////////////////////////////////////////////////////////////////////
6179     HRESULT GetManagedContext( DT_CONTEXT ** ppContext );
6180     HRESULT SetManagedContext( DT_CONTEXT * pContext );
6181
6182     // API to retrieve the thread handle from the LS.
6183     void InternalGetHandle(HANDLE * phThread);
6184     void RefreshHandle(HANDLE * phThread);
6185
6186     // NeuterList that's executed when this Thread's stack is refreshed.
6187     // Chain + Frame + some Value enums can be held on this.
6188     NeuterList * GetRefreshStackNeuterList()
6189     {
6190         return &m_RefreshStackNeuterList;
6191     }
6192
6193     DWORD GetUniqueId();
6194
6195
6196     // Hijack a thread at a 2nd-chance exception so that it can execute the CLR's UEF
6197     void HijackForUnhandledException();
6198
6199     // check whether the specified frame lives on the stack of the current thread
6200     bool OwnsFrame(CordbFrame *pFrame);
6201
6202     // Specify that there's an outstanding exception on this thread.
6203     void SetExInfo(VMPTR_OBJECTHANDLE vmExcepObjHandle);
6204
6205     VMPTR_OBJECTHANDLE GetThreadExceptionRawObjectHandle() { return m_vmExcepObjHandle; }
6206     bool HasException() { return m_fException; }
6207
6208     void SetUnhandledNativeException(const EXCEPTION_RECORD * pExceptionRecord);
6209     bool HasUnhandledNativeException();
6210
6211 #ifdef _DEBUG
6212     // Helper to assert that this thread no longer appears in dac-dbi enumerations
6213     void DbgAssertThreadDeleted();
6214
6215     // Callback for DbgAssertThreadDeleted
6216     static void DbgAssertThreadDeletedCallback(VMPTR_Thread vmThread, void * pUserData);
6217 #endif // _DEBUG
6218
6219     // Determine if the thread's current exception is managed or unmanaged.
6220     BOOL IsThreadExceptionManaged();
6221
6222     // This is a private hook for the shim to create a CordbRegisterSet for a ShimChain.
6223    void CreateCordbRegisterSet(DT_CONTEXT *            pContext, 
6224                                BOOL                    fActive,
6225                                CorDebugChainReason     reason,
6226                                ICorDebugRegisterSet ** ppRegSet);
6227
6228     // This is a private hook for the shim to convert an ICDFrame into an ICDInternalFrame for a dynamic
6229     // method.  Refer to the function header for more information.
6230    BOOL ConvertFrameForILMethodWithoutMetadata(ICorDebugFrame *           pFrame,
6231                                                ICorDebugInternalFrame2 ** ppInternalFrame2);
6232
6233     // Gets/sets m_fCreationEventQueued
6234     bool CreateEventWasQueued();
6235     void SetCreateEventQueued();
6236
6237     //-----------------------------------------------------------
6238     // Data members
6239     //-----------------------------------------------------------
6240
6241 public:
6242     // RS Cache for LS context.
6243     // NULL if we haven't allocated memory for a Right side context
6244     DT_CONTEXT *          m_pContext;
6245
6246     // Set to the CONTEXT pointer in the LS if this LS thread is
6247     // stopped in managed code. This may be either stopped for execution control
6248     // (breakpoint / single-step exception) or hijacked w/ a redirected frame because
6249     // another thread synced the LS.
6250     // This context is used by the RS to set enregistered vars.
6251     VMPTR_CONTEXT         m_vmLeftSideContext;
6252
6253     // indicates whether m_pContext is up-to-date
6254     bool                  m_fContextFresh;
6255
6256     // last domain we've seen this thread.
6257     // If the appdomain exits, it will clear out this value.
6258     CordbAppDomain       *m_pAppDomain;
6259
6260     // Handle to VM's Thread* object. This is the primary key for a CordbThread object
6261     // @dbgtodo  ICDThread - merge with m_id;
6262     VMPTR_Thread          m_vmThreadToken;
6263
6264     // Unique ID for this thread. See code:CordbThread::GetID for semantics of this field.
6265     DWORD                 m_dwUniqueID;
6266
6267     CorDebugThreadState   m_debugState; // Note that this is for resume
6268                                         // purposes, NOT the current state of
6269                                         // the thread.
6270
6271     // The frames are all protected under the Stop-Go lock.
6272     // This field indicates whether the stack is valid (i.e. no update is necessary).
6273     bool                  m_fFramesFresh;
6274
6275     // This is a cache of V3 ICDFrames.  The cache is only used by two functions: 
6276     //     - code:CordbThread::GetActiveFunctions 
6277     //     - code:CordbThread::InterceptCurrentException.
6278     //     
6279     //  We don't clear the cache in CleanupStack() because we don't refresh the cache every time we stop.  
6280     //  Instead, we mark m_fFramesFresh in CleanupStack() and clear the cache only when it is used next time.
6281     CDynArray<CordbFrame *> m_stackFrames;
6282
6283 #if !defined(DBG_TARGET_ARM) // @ARMTODO
6284     bool                  m_fFloatStateValid;
6285     unsigned int          m_floatStackTop;
6286     double                m_floatValues[DebuggerIPCE_FloatCount];
6287 #endif // !DBG_TARGET_ARM @ARMTODO
6288
6289 private:
6290     // True for the window after an Exception callback, but before it's been continued.
6291     // We dispatch two exception events in a row (ICDManagedCallback::Exception and ICDManagedCallback2::Exception),
6292     // and a debugger may normally just skip the first one knowing it can stop on the 2nd once.
6293     // Both events will set this bit high. Be careful not to reset this bit inbetween them.
6294     bool                  m_fException;
6295
6296     // True if a creation event has been queued for this thread
6297     // The event may or may not have been dispatched yet
6298     // Bugfix DevDiv2\DevDiv 77523 - this is only being set from ShimProcess::QueueFakeThreadAttachEventsNativeOrder
6299     bool                  m_fCreationEventQueued;
6300
6301     // Object handle for Exception object in debuggee.
6302     VMPTR_OBJECTHANDLE    m_vmExcepObjHandle;
6303    
6304 public:
6305
6306     //Returns true if current user state of a thread is USER_WAIT_SLEEP_JOIN
6307     bool IsThreadWaitingOrSleeping();
6308
6309     // Returns true if the thread is dead. See function header for definition.
6310     bool IsThreadDead();
6311
6312     // Return CORDBG_E_BAD_THREAD_STATE if the thread is dead.
6313     HRESULT EnsureThreadIsAlive();
6314
6315     // On a RemapBreakpoint, the debugger will eventually call RemapFunction and
6316     // we need to communicate the IP back to LS. So we stash the address of where
6317     // to store the IP here and stuff it in on RemapFunction.
6318     // If we're not at an outstanding RemapOpportunity, this will be NULL
6319     REMOTE_PTR            m_EnCRemapFunctionIP;
6320
6321 private:
6322     void ClearStackFrameCache();
6323
6324     // True iff this thread has an unhandled exception on it. 
6325     // Set high when Filter() gets noitifed of an unhandled exception.
6326     // Set Low if the thread is hijacked.
6327     bool                  m_fHasUnhandledException;
6328
6329     // Exception record for last unhandled exception on this thread.
6330     // Lazily initialized. 
6331     EXCEPTION_RECORD *  m_pExceptionRecord; 
6332
6333     static const CorDebugUserState kInvalidUserState = CorDebugUserState(-1);
6334     CorDebugUserState     m_userState;  // This is the current state of the
6335                                         // thread, at the time that the
6336                                         // left side synchronized
6337
6338     // NeuterList that's executed when this Thread's stack is refreshed.
6339     // This list is for everything related to stackwalking, i.e. everything which is invalidated 
6340     // if the stack changes in any way.  This list is cleared when any of the following is called:
6341     //     1) Continue()
6342     //     2) SetIP()
6343     //     3) RemapFunction()
6344     //     4) ICDProcess::SetThreadContext()
6345     NeuterList            m_RefreshStackNeuterList;
6346
6347     // The following two data members are used for caching thread handles.
6348     // @dbgtodo  - Remove in V3 (can't have local handles with data-target abstraction); 
6349     // offload to the shim to support V2 scenarios.
6350     HANDLE                m_hCachedThread;
6351     HANDLE                m_hCachedOutOfProcThread;
6352 };
6353
6354 /* ------------------------------------------------------------------------- *
6355  * StackWalk class
6356  * ------------------------------------------------------------------------- */
6357
6358 class CordbStackWalk : public CordbBase, public ICorDebugStackWalk
6359 {
6360 public:
6361     CordbStackWalk(CordbThread * pCordbThread);
6362     virtual ~CordbStackWalk();
6363     virtual void Neuter();
6364
6365     // helper function for Neuter
6366     virtual void DeleteAll();
6367
6368     using CordbBase::GetProcess;
6369     
6370 #ifdef _DEBUG
6371     virtual const char * DbgGetName() { return "CordbStackWalk"; }
6372 #endif
6373
6374     //-----------------------------------------------------------
6375     // IUnknown
6376     //-----------------------------------------------------------
6377
6378     ULONG STDMETHODCALLTYPE AddRef()
6379     {
6380         return (BaseAddRef());
6381     }
6382     ULONG STDMETHODCALLTYPE Release()
6383     {
6384         return (BaseRelease());
6385     }
6386     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6387
6388     //-----------------------------------------------------------
6389     // ICorDebugStackWalk
6390     //-----------------------------------------------------------
6391
6392     COM_METHOD GetContext(ULONG32   contextFlags,
6393                           ULONG32   contextBufSize,
6394                           ULONG32 * pContextSize,
6395                           BYTE      pbContextBuf[]);
6396     COM_METHOD SetContext(CorDebugSetContextFlag flag, ULONG32 contextSize, BYTE context[]);
6397     COM_METHOD Next();
6398     COM_METHOD GetFrame(ICorDebugFrame **ppFrame);
6399
6400     //-----------------------------------------------------------
6401     // Internal members
6402     //-----------------------------------------------------------
6403
6404     void SetContextWorker(CorDebugSetContextFlag flag, ULONG32 contextSize, BYTE context[]);
6405     HRESULT GetFrameWorker(ICorDebugFrame **ppFrame);
6406
6407     //-----------------------------------------------------------
6408     // Data members
6409     //-----------------------------------------------------------
6410
6411 public:
6412     void Init();
6413
6414 private:
6415     // handle legacy V2 hijacking for unhandled hardware exceptions
6416     void CheckForLegacyHijackCase();
6417
6418     // refresh the data for this instance of CordbStackWalk if we have had an IPC event followed by a
6419     // continue since we got the information.
6420     void RefreshIfNeeded();
6421
6422     // unwind the frame and update m_context with the new context
6423     BOOL UnwindStackFrame();
6424
6425     // the thread on which this CordbStackWalk is created
6426     CordbThread * m_pCordbThread;
6427
6428     // This is the same iterator used by the runtime itself.
6429     IDacDbiInterface::StackWalkHandle m_pSFIHandle;
6430
6431     // buffers used for stackwalking
6432     DT_CONTEXT m_context;
6433
6434     //  Used to figure out if we have to refresh any reference objects
6435     //  on the left side.  We set it to CordbProcess::m_flushCounter on 
6436     //  creation and will check it against that value when we call GetFrame or Next.
6437     //  If it doesn't match, an IPC event has occurred and the values will need to be 
6438     //  refreshed via the DAC.
6439     UINT m_lastSyncFlushCounter;
6440
6441     // cached flag used for refreshing a CordbStackWalk
6442     CorDebugSetContextFlag m_cachedSetContextFlag;
6443
6444     // We unwind one frame ahead of time to get the FramePointer on x86.
6445     // These fields are used for the bookkeeping.
6446     RSSmartPtr<CordbFrame> m_pCachedFrame;
6447     HRESULT m_cachedHR;
6448     bool m_fIsOneFrameAhead;
6449 };
6450
6451
6452 class CordbContext : public CordbBase, public ICorDebugContext
6453 {
6454 public:
6455
6456     CordbContext() : CordbBase(NULL, 0, enumCordbContext) {}
6457
6458
6459
6460 #ifdef _DEBUG
6461     virtual const char * DbgGetName() { return "CordbContext"; }
6462 #endif
6463
6464
6465     //-----------------------------------------------------------
6466     // IUnknown
6467     //-----------------------------------------------------------
6468
6469     ULONG STDMETHODCALLTYPE AddRef()
6470     {
6471         return (BaseAddRef());
6472     }
6473     ULONG STDMETHODCALLTYPE Release()
6474     {
6475         return (BaseRelease());
6476     }
6477     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6478
6479     //-----------------------------------------------------------
6480     // ICorDebugContext
6481     //-----------------------------------------------------------
6482 private:
6483
6484 } ;
6485
6486
6487 /* ------------------------------------------------------------------------- *
6488  * Frame class
6489  * ------------------------------------------------------------------------- */
6490
6491 class CordbFrame : public CordbBase, public ICorDebugFrame
6492 {
6493 protected:
6494     // Ctor to provide dummy frame that just wraps a frame-pointer
6495     CordbFrame(CordbProcess * pProcess, FramePointer fp);
6496
6497 public:
6498     CordbFrame(CordbThread *    pThread,
6499                FramePointer     fp,
6500                SIZE_T           ip, 
6501                CordbAppDomain * pCurrentAppDomain);
6502
6503     virtual ~CordbFrame();
6504     virtual void Neuter();
6505
6506 #ifdef _DEBUG
6507     virtual const char * DbgGetName() { return "CordbFrame"; }
6508 #endif
6509
6510     //-----------------------------------------------------------
6511     // IUnknown
6512     //-----------------------------------------------------------
6513
6514     ULONG STDMETHODCALLTYPE AddRef()
6515     {
6516         return (BaseAddRef());
6517     }
6518     ULONG STDMETHODCALLTYPE Release()
6519     {
6520         return (BaseRelease());
6521     }
6522     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6523
6524     //-----------------------------------------------------------
6525     // ICorDebugFrame
6526     //-----------------------------------------------------------
6527
6528     COM_METHOD GetChain(ICorDebugChain **ppChain);
6529
6530     // Derived versions of Frame will implement GetCode.
6531     COM_METHOD GetCode(ICorDebugCode **ppCode) = 0;
6532
6533     COM_METHOD GetFunction(ICorDebugFunction **ppFunction);
6534     COM_METHOD GetFunctionToken(mdMethodDef *pToken);
6535
6536     COM_METHOD GetStackRange(CORDB_ADDRESS *pStart, CORDB_ADDRESS *pEnd);
6537     COM_METHOD GetCaller(ICorDebugFrame **ppFrame);
6538     COM_METHOD GetCallee(ICorDebugFrame **ppFrame);
6539     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper);
6540
6541     //-----------------------------------------------------------
6542     // Convenience routines
6543     //-----------------------------------------------------------
6544
6545     CordbAppDomain *GetCurrentAppDomain()
6546     {
6547         return m_currentAppDomain;
6548     }
6549
6550     // Internal helper to get a CordbFunction for this frame.
6551     virtual CordbFunction *GetFunction() = 0;
6552
6553     FramePointer GetFramePointer()
6554     {
6555         return m_fp;
6556     }
6557
6558     //-----------------------------------------------------------
6559     // Data members
6560     //-----------------------------------------------------------
6561
6562     // Accessors to return NULL or typesafe cast to derived frame
6563     virtual CordbInternalFrame * GetAsInternalFrame()   { return NULL; }
6564     virtual CordbNativeFrame * GetAsNativeFrame()       { return NULL; }
6565
6566     // determine if the frame pointer is in the stack range owned by the frame
6567     bool IsContainedInFrame(FramePointer fp);
6568
6569     // This is basically a complicated cast function.  We are casting from an ICorDebugFrame to a CordbFrame.
6570     static CordbFrame* GetCordbFrameFromInterface(ICorDebugFrame *pFrame);
6571
6572     virtual const DT_CONTEXT * GetContext() const { return NULL; }
6573
6574 public:
6575     // this represents the IL offset for a CordbJITILFrame, the native offset for a CordbNativeFrame, 
6576     // and 0 for a CordbInternalFrame
6577     SIZE_T                  m_ip;
6578
6579     CordbThread *           m_pThread;
6580
6581     CordbAppDomain         *m_currentAppDomain;
6582     FramePointer            m_fp;
6583
6584 protected:
6585     // indicates whether this frame is the leaf frame; lazily initialized
6586     mutable Optional<bool>  m_optfIsLeafFrame;
6587
6588 private:
6589 #ifdef _DEBUG
6590     // For tracking down neutering bugs;
6591     UINT                   m_DbgContinueCounter;
6592 #endif
6593 };
6594
6595 // Dummy frame that just wraps a frame pointer.
6596 // This is used to pass a FramePointer back in the Exception2 callback.
6597 // Currently, the callback passes back an ICorDebugFrame as a way of exposing a cross-platform
6598 // frame pointer. However passing back an ICDFrame means we need to do a stackwalk, and
6599 // that may not be possible in V3:
6600 // - the stackwalk is very chatty, and may be too much work just to give an exception notification.
6601 // - in 64-bit, we may not even be able to do the stackwalk ourselves.
6602 //
6603 // The shim can take the framePointer and do the stackwalk and resolve it to a real frame,
6604 // so V2 emulation scenarios will continue to work.
6605 // @dbgtodo  exception -  resolve this when we iron out exceptions in V3.
6606 class CordbPlaceholderFrame : public CordbFrame
6607 {
6608 public:
6609     // Ctor to provide dummy frame that just wraps a frame-pointer
6610     CordbPlaceholderFrame(CordbProcess * pProcess, FramePointer fp)
6611         : CordbFrame(pProcess, fp)
6612     {
6613     }
6614
6615 #ifdef _DEBUG
6616     virtual const char * DbgGetName() { return "CordbFrame"; }
6617 #endif
6618
6619     // Provide dummy implementation for some methods. These should never be called.
6620     COM_METHOD GetCode(ICorDebugCode **ppCode) 
6621     { 
6622         _ASSERTE(!"Don't call this");
6623         return E_NOTIMPL; 
6624     }
6625     virtual CordbFunction *GetFunction() 
6626     { 
6627         _ASSERTE(!"Don't call this");
6628         return NULL; 
6629     } 
6630 };
6631
6632 class CordbInternalFrame : public CordbFrame, public ICorDebugInternalFrame, public ICorDebugInternalFrame2
6633 {
6634 public:
6635     CordbInternalFrame(CordbThread *          pThread,
6636                        FramePointer           fp,
6637                        CordbAppDomain *       pCurrentAppDomain,
6638                        const DebuggerIPCE_STRData * pData);
6639
6640     CordbInternalFrame(CordbThread *             pThread,
6641                        FramePointer              fp,
6642                        CordbAppDomain *       pCurrentAppDomain,
6643                        CorDebugInternalFrameType frameType,
6644                        mdMethodDef               funcMetadataToken,
6645                        CordbFunction *           pFunction,
6646                        VMPTR_MethodDesc          vmMethodDesc);
6647
6648     virtual void Neuter();
6649
6650 #ifdef _DEBUG
6651     virtual const char * DbgGetName() { return "CordbInternalFrame"; }
6652 #endif
6653
6654     //-----------------------------------------------------------
6655     // IUnknown
6656     //-----------------------------------------------------------
6657
6658     ULONG STDMETHODCALLTYPE AddRef()
6659     {
6660         return (BaseAddRef());
6661     }
6662     ULONG STDMETHODCALLTYPE Release()
6663     {
6664         return (BaseRelease());
6665     }
6666     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6667
6668     //-----------------------------------------------------------
6669     // ICorDebugFrame
6670     //-----------------------------------------------------------
6671
6672     COM_METHOD GetChain(ICorDebugChain **ppChain)
6673     {
6674         return (CordbFrame::GetChain(ppChain));
6675     }
6676
6677     // We don't expose a code-object for stubs.
6678     COM_METHOD GetCode(ICorDebugCode **ppCode)
6679     {
6680         return CORDBG_E_CODE_NOT_AVAILABLE;
6681     }
6682
6683     COM_METHOD GetFunction(ICorDebugFunction **ppFunction)
6684     {
6685         return (CordbFrame::GetFunction(ppFunction));
6686     }
6687     COM_METHOD GetFunctionToken(mdMethodDef *pToken)
6688     {
6689         return (CordbFrame::GetFunctionToken(pToken));
6690     }
6691
6692     COM_METHOD GetCaller(ICorDebugFrame **ppFrame)
6693     {
6694         return (CordbFrame::GetCaller(ppFrame));
6695     }
6696     COM_METHOD GetCallee(ICorDebugFrame **ppFrame)
6697     {
6698         return (CordbFrame::GetCallee(ppFrame));
6699     }
6700     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper)
6701     {
6702         return E_NOTIMPL;
6703     }
6704
6705     COM_METHOD GetStackRange(CORDB_ADDRESS *pStart, CORDB_ADDRESS *pEnd);
6706
6707     //-----------------------------------------------------------
6708     // ICorDebugInternalFrame
6709     //-----------------------------------------------------------
6710
6711     // Get the type of internal frame. This will never be STUBFRAME_NONE.
6712     COM_METHOD GetFrameType(CorDebugInternalFrameType * pType)
6713     {
6714         VALIDATE_POINTER_TO_OBJECT(pType, CorDebugInternalFrameType)
6715         *pType = m_eFrameType;
6716         return S_OK;
6717     }
6718
6719     //-----------------------------------------------------------
6720     // ICorDebugInternalFrame2
6721     //-----------------------------------------------------------
6722
6723     COM_METHOD GetAddress(CORDB_ADDRESS * pAddress);
6724     COM_METHOD IsCloserToLeaf(ICorDebugFrame * pFrameToCompare, 
6725                               BOOL *           pIsCloser);
6726
6727     BOOL IsCloserToLeafWorker(ICorDebugFrame * pFrameToCompare);
6728
6729     //-----------------------------------------------------------
6730     // Non COM methods
6731     //-----------------------------------------------------------
6732
6733     virtual CordbFunction *GetFunction();
6734
6735
6736     // Accessors to return NULL or typesafe cast to derived frame
6737     virtual CordbInternalFrame * GetAsInternalFrame()   { return this; }
6738
6739     // accessor for the shim private hook code:CordbThread::ConvertFrameForILMethodWithoutMetadata
6740     BOOL ConvertInternalFrameForILMethodWithoutMetadata(ICorDebugInternalFrame2 ** ppInternalFrame2);
6741
6742 protected:
6743     // the frame type
6744     CorDebugInternalFrameType m_eFrameType;
6745     
6746     // the method token of the method (if any) associated with the internal frame
6747     mdMethodDef m_funcMetadataToken;
6748
6749     // the method (if any) associated with the internal frame
6750     RSSmartPtr<CordbFunction> m_function;
6751
6752     VMPTR_MethodDesc          m_vmMethodDesc;
6753 };
6754
6755 //---------------------------------------------------------------------------------------
6756 //
6757 // This class implements ICorDebugRuntimeUnwindableFrame.  It is used to mark a native stack frame 
6758 // which requires special unwinding and which doesn't correspond to any IL code.  It is really
6759 // just a marker to tell the debugger to use the managed unwinder.  The debugger is still responsible
6760 // to do all the inspection and symbol lookup.  An example is the hijack stub.
6761 //
6762
6763 class CordbRuntimeUnwindableFrame : public CordbFrame, public ICorDebugRuntimeUnwindableFrame
6764 {
6765 public:
6766     CordbRuntimeUnwindableFrame(CordbThread *    pThread,
6767                                 FramePointer     fp,
6768                                 CordbAppDomain * pCurrentAppDomain,
6769                                 DT_CONTEXT *     pContext);
6770
6771     virtual void Neuter();
6772
6773 #ifdef _DEBUG
6774     virtual const char * DbgGetName() { return "CordbRuntimeUnwindableFrame"; }
6775 #endif
6776
6777     //-----------------------------------------------------------
6778     // IUnknown
6779     //-----------------------------------------------------------
6780
6781     ULONG STDMETHODCALLTYPE AddRef()
6782     {
6783         return (BaseAddRef());
6784     }
6785
6786     ULONG STDMETHODCALLTYPE Release()
6787     {
6788         return (BaseRelease());
6789     }
6790
6791     COM_METHOD QueryInterface(REFIID riid, void ** ppInterface);
6792
6793     //-----------------------------------------------------------
6794     // ICorDebugFrame
6795     //-----------------------------------------------------------
6796
6797     // 
6798     // Just return E_NOTIMPL for everything.  
6799     // See the class comment.
6800     //
6801
6802     COM_METHOD GetChain(ICorDebugChain ** ppChain)
6803     {
6804         return E_NOTIMPL;
6805     }
6806
6807     COM_METHOD GetCode(ICorDebugCode ** ppCode)
6808     {
6809         return E_NOTIMPL;
6810     }
6811
6812     COM_METHOD GetFunction(ICorDebugFunction ** ppFunction)
6813     {
6814         return E_NOTIMPL;
6815     }
6816
6817     COM_METHOD GetFunctionToken(mdMethodDef * pToken)
6818     {
6819         return E_NOTIMPL;
6820     }
6821
6822     COM_METHOD GetCaller(ICorDebugFrame ** ppFrame)
6823     {
6824         return E_NOTIMPL;
6825     }
6826
6827     COM_METHOD GetCallee(ICorDebugFrame ** ppFrame)
6828     {
6829         return E_NOTIMPL;
6830     }
6831
6832     COM_METHOD CreateStepper(ICorDebugStepper ** ppStepper)
6833     {
6834         return E_NOTIMPL;
6835     }
6836
6837     COM_METHOD GetStackRange(CORDB_ADDRESS * pStart, CORDB_ADDRESS * pEnd)
6838     {
6839         return E_NOTIMPL;
6840     }
6841
6842     //-----------------------------------------------------------
6843     // Non COM methods
6844     //-----------------------------------------------------------
6845
6846     virtual CordbFunction * GetFunction()
6847     {
6848         return NULL;
6849     }
6850
6851     virtual const DT_CONTEXT * GetContext() const;
6852
6853 private:
6854     DT_CONTEXT m_context;
6855 };
6856
6857
6858 class CordbValueEnum : public CordbBase, public ICorDebugValueEnum
6859 {
6860 public:
6861     enum ValueEnumMode {
6862         LOCAL_VARS_ORIGINAL_IL,
6863         LOCAL_VARS_REJIT_IL,
6864         ARGS,
6865     } ;
6866
6867     CordbValueEnum(CordbNativeFrame *frame, ValueEnumMode mode);
6868     HRESULT Init();
6869     ~CordbValueEnum();
6870     virtual void Neuter();
6871
6872 #ifdef _DEBUG
6873     virtual const char * DbgGetName() { return "CordbValueEnum"; }
6874 #endif
6875
6876
6877     //-----------------------------------------------------------
6878     // IUnknown
6879     //-----------------------------------------------------------
6880
6881     ULONG STDMETHODCALLTYPE AddRef()
6882     {
6883         return (BaseAddRef());
6884     }
6885     ULONG STDMETHODCALLTYPE Release()
6886     {
6887         return (BaseRelease());
6888     }
6889     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6890
6891     //-----------------------------------------------------------
6892     // ICorDebugEnum
6893     //-----------------------------------------------------------
6894
6895     COM_METHOD Skip(ULONG celt);
6896     COM_METHOD Reset();
6897     COM_METHOD Clone(ICorDebugEnum **ppEnum);
6898     COM_METHOD GetCount(ULONG *pcelt);
6899
6900     //-----------------------------------------------------------
6901     // ICorDebugValueEnum
6902     //-----------------------------------------------------------
6903
6904     COM_METHOD Next(ULONG celt, ICorDebugValue *values[], ULONG *pceltFetched);
6905
6906 private:
6907     CordbNativeFrame*     m_frame;
6908     ValueEnumMode   m_mode;
6909     UINT            m_iCurrent;
6910     UINT            m_iMax;
6911 };
6912
6913
6914 /* ------------------------------------------------------------------------- *
6915  * Misc Info for the Native Frame class
6916  * ------------------------------------------------------------------------- */
6917
6918 struct CordbMiscFrame
6919 {
6920 public:
6921     CordbMiscFrame();
6922
6923     // new-style constructor
6924     CordbMiscFrame(DebuggerIPCE_JITFuncData * pJITFuncData);
6925
6926 #ifdef WIN64EXCEPTIONS
6927     SIZE_T             parentIP;
6928     FramePointer       fpParentOrSelf;
6929     bool               fIsFilterFunclet;
6930 #endif // WIN64EXCEPTIONS
6931 };
6932
6933
6934 /* ------------------------------------------------------------------------- *
6935  * Native Frame class
6936  * ------------------------------------------------------------------------- */
6937
6938 class CordbNativeFrame : public CordbFrame, public ICorDebugNativeFrame, public ICorDebugNativeFrame2
6939 {
6940 public:
6941     CordbNativeFrame(CordbThread *        pThread,
6942                      FramePointer         fp,
6943                      CordbNativeCode *    pNativeCode,
6944                      SIZE_T               ip, 
6945                      DebuggerREGDISPLAY * pDRD,
6946                      TADDR                addrAmbientESP,
6947                      bool                 fQuicklyUnwound,
6948                      CordbAppDomain *     pCurrentAppDomain,
6949                      CordbMiscFrame *     pMisc = NULL,
6950                      DT_CONTEXT *         pContext = NULL);
6951     virtual ~CordbNativeFrame();
6952     virtual void Neuter();
6953
6954 #ifdef _DEBUG
6955     virtual const char * DbgGetName() { return "CordbNativeFrame"; }
6956 #endif
6957
6958     //-----------------------------------------------------------
6959     // IUnknown
6960     //-----------------------------------------------------------
6961
6962     ULONG STDMETHODCALLTYPE AddRef()
6963     {
6964         return (BaseAddRef());
6965     }
6966     ULONG STDMETHODCALLTYPE Release()
6967     {
6968         return (BaseRelease());
6969     }
6970     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6971
6972     //-----------------------------------------------------------
6973     // ICorDebugFrame
6974     //-----------------------------------------------------------
6975
6976     COM_METHOD GetChain(ICorDebugChain **ppChain)
6977     {
6978         return (CordbFrame::GetChain(ppChain));
6979     }
6980     COM_METHOD GetCode(ICorDebugCode **ppCode);
6981     COM_METHOD GetFunction(ICorDebugFunction **ppFunction)
6982     {
6983         return (CordbFrame::GetFunction(ppFunction));
6984     }
6985     COM_METHOD GetFunctionToken(mdMethodDef *pToken)
6986     {
6987         return (CordbFrame::GetFunctionToken(pToken));
6988     }
6989     COM_METHOD GetCaller(ICorDebugFrame **ppFrame)
6990     {
6991         return (CordbFrame::GetCaller(ppFrame));
6992     }
6993     COM_METHOD GetCallee(ICorDebugFrame **ppFrame)
6994     {
6995         return (CordbFrame::GetCallee(ppFrame));
6996     }
6997     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper)
6998     {
6999         return (CordbFrame::CreateStepper(ppStepper));
7000     }
7001
7002     COM_METHOD GetStackRange(CORDB_ADDRESS *pStart, CORDB_ADDRESS *pEnd);
7003
7004     //-----------------------------------------------------------
7005     // ICorDebugNativeFrame
7006     //-----------------------------------------------------------
7007
7008     COM_METHOD GetIP(ULONG32* pnOffset);
7009     COM_METHOD SetIP(ULONG32 nOffset);
7010     COM_METHOD GetRegisterSet(ICorDebugRegisterSet **ppRegisters);
7011     COM_METHOD GetLocalRegisterValue(CorDebugRegister reg,
7012                                      ULONG cbSigBlob,
7013                                      PCCOR_SIGNATURE pvSigBlob,
7014                                      ICorDebugValue ** ppValue);
7015
7016     COM_METHOD GetLocalDoubleRegisterValue(CorDebugRegister highWordReg,
7017                                            CorDebugRegister lowWordReg,
7018                                            ULONG cbSigBlob,
7019                                            PCCOR_SIGNATURE pvSigBlob,
7020                                            ICorDebugValue ** ppValue);
7021
7022     COM_METHOD GetLocalMemoryValue(CORDB_ADDRESS address,
7023                                    ULONG cbSigBlob,
7024                                    PCCOR_SIGNATURE pvSigBlob,
7025                                    ICorDebugValue ** ppValue);
7026
7027     COM_METHOD GetLocalRegisterMemoryValue(CorDebugRegister highWordReg,
7028                                            CORDB_ADDRESS lowWordAddress,
7029                                            ULONG cbSigBlob,
7030                                            PCCOR_SIGNATURE pvSigBlob,
7031                                            ICorDebugValue ** ppValue);
7032
7033     COM_METHOD GetLocalMemoryRegisterValue(CORDB_ADDRESS highWordAddress,
7034                                            CorDebugRegister lowWordRegister,
7035                                            ULONG cbSigBlob,
7036                                            PCCOR_SIGNATURE pvSigBlob,
7037                                            ICorDebugValue ** ppValue);
7038
7039     COM_METHOD CanSetIP(ULONG32 nOffset);
7040
7041     //-----------------------------------------------------------
7042     // ICorDebugNativeFrame2
7043     //-----------------------------------------------------------
7044
7045     COM_METHOD IsChild(BOOL * pIsChild);
7046
7047     COM_METHOD IsMatchingParentFrame(ICorDebugNativeFrame2 *pPotentialParentFrame,
7048                                      BOOL * pIsParent);
7049
7050     COM_METHOD GetStackParameterSize(ULONG32 * pSize);
7051
7052     //-----------------------------------------------------------
7053     // Non-COM members
7054     //-----------------------------------------------------------
7055
7056     // Accessors to return NULL or typesafe cast to derived frame
7057     virtual CordbNativeFrame * GetAsNativeFrame()       { return this; }
7058
7059     CordbFunction * GetFunction();
7060     CordbNativeCode * GetNativeCode();
7061     virtual const DT_CONTEXT * GetContext() const;
7062
7063     // Given the native variable information of a variable, return its value.
7064     // This function assumes that the value is either in a register or on the stack
7065     // (i.e. VLT_REG or VLT_STK).
7066     SIZE_T  GetRegisterOrStackValue(const ICorDebugInfo::NativeVarInfo * pNativeVarInfo);
7067
7068     HRESULT GetLocalRegisterValue(CorDebugRegister reg,
7069                                      CordbType * pType,
7070                                      ICorDebugValue **ppValue);
7071     HRESULT GetLocalDoubleRegisterValue(CorDebugRegister highWordReg,
7072                                            CorDebugRegister lowWordReg,
7073                                            CordbType * pType,
7074                                            ICorDebugValue **ppValue);
7075     HRESULT GetLocalMemoryValue(CORDB_ADDRESS address,
7076                                    CordbType * pType,
7077                                    ICorDebugValue **ppValue);
7078     HRESULT GetLocalByRefMemoryValue(CORDB_ADDRESS address,
7079                                         CordbType * pType,
7080                                         ICorDebugValue **ppValue);
7081     HRESULT GetLocalRegisterMemoryValue(CorDebugRegister highWordReg,
7082                                            CORDB_ADDRESS lowWordAddress,
7083                                            CordbType * pType,
7084                                            ICorDebugValue **ppValue);
7085     HRESULT GetLocalMemoryRegisterValue(CORDB_ADDRESS highWordAddress,
7086                                            CorDebugRegister lowWordRegister,
7087                                            CordbType * pType,
7088                                            ICorDebugValue **ppValue);
7089     UINT_PTR * GetAddressOfRegister(CorDebugRegister regNum) const;
7090     CORDB_ADDRESS GetLeftSideAddressOfRegister(CorDebugRegister regNum) const;
7091 #if !defined(DBG_TARGET_ARM) // @ARMTODO
7092     HRESULT GetLocalFloatingPointValue(DWORD index,
7093                                             CordbType * pType,
7094                                             ICorDebugValue **ppValue);
7095 #endif // !DBG_TARGET_ARM @ARMTODO
7096
7097
7098     CORDB_ADDRESS GetLSStackAddress(ICorDebugInfo::RegNum regNum, signed offset);
7099
7100     bool IsLeafFrame() const;
7101
7102     // Return the offset used for inspection purposes.  
7103     // Refer to the comment at the beginning of the function definition in RsThread.cpp for more information.
7104     SIZE_T GetInspectionIP();
7105     
7106     ULONG32 GetIPOffset();
7107
7108     // whether this is a funclet frame
7109     bool      IsFunclet();
7110     bool      IsFilterFunclet();
7111
7112 #if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
7113     // return the offset of the parent method frame at which an exception occurs
7114     SIZE_T    GetParentIP();
7115 #endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
7116
7117     TADDR GetAmbientESP() { return m_taAmbientESP; }
7118     TADDR GetReturnRegisterValue();
7119
7120     // accessor for the shim private hook code:CordbThread::ConvertFrameForILMethodWithoutMetadata
7121     BOOL ConvertNativeFrameForILMethodWithoutMetadata(ICorDebugInternalFrame2 ** ppInternalFrame2);
7122
7123     //-----------------------------------------------------------
7124     // Data members
7125     //-----------------------------------------------------------
7126
7127 public:
7128     // the register set
7129     DebuggerREGDISPLAY m_rd;
7130
7131     // This field is only true for Enter-Managed chain.  It means that the register set is invalid.
7132     bool               m_quicklyUnwound;
7133
7134     // each CordbNativeFrame corresponds to exactly one CordbJITILFrame and one CordbNativeCode
7135     RSSmartPtr<CordbJITILFrame> m_JITILFrame;
7136     RSSmartPtr<CordbNativeCode> m_nativeCode;
7137
7138     // auxiliary information only used on 64-bit to find the parent stack pointer and offset for funclets
7139     CordbMiscFrame     m_misc;
7140
7141 private:
7142     // the ambient SP value only used on x86 to retrieve sp-relative local variables 
7143     // (most likely in a frameless method)
7144     TADDR    m_taAmbientESP;
7145
7146     // @dbgtodo  inspection - When we DACize the various Cordb*Value classes, we should consider getting rid of the
7147     // DebuggerREGDISPLAY and just use the CONTEXT.  A lot of simplification can be done here.
7148     DT_CONTEXT  m_context;
7149 };
7150
7151
7152 /* ------------------------------------------------------------------------- *
7153  * CordbRegisterSet class
7154  *
7155  * This can be obtained via GetRegisterSet from
7156  *      CordbNativeFrame
7157  *      CordbThread
7158  *
7159  * ------------------------------------------------------------------------- */
7160
7161 #define SETBITULONG64( x ) ( (ULONG64)1 << (x) )
7162 #define SET_BIT_MASK(_mask, _reg)      (_mask[(_reg) >> 3] |=  (1 << ((_reg) & 7)))
7163 #define RESET_BIT_MASK(_mask, _reg)    (_mask[(_reg) >> 3] &= ~(1 << ((_reg) & 7)))
7164 #define IS_SET_BIT_MASK(_mask, _reg)   (_mask[(_reg) >> 3] &   (1 << ((_reg) & 7)))
7165
7166
7167 class CordbRegisterSet : public CordbBase, public ICorDebugRegisterSet, public ICorDebugRegisterSet2
7168 {
7169 public:
7170     CordbRegisterSet(DebuggerREGDISPLAY * pRegDisplay, 
7171                      CordbThread *        pThread,
7172                      bool fActive, 
7173                      bool fQuickUnwind,
7174                      bool fTakeOwnershipOfDRD = false);
7175
7176
7177     ~CordbRegisterSet();
7178
7179
7180
7181     virtual void Neuter();
7182
7183 #ifdef _DEBUG
7184     virtual const char * DbgGetName() { return "CordbRegisterSet"; }
7185 #endif
7186
7187     //-----------------------------------------------------------
7188     // IUnknown
7189     //-----------------------------------------------------------
7190
7191     ULONG STDMETHODCALLTYPE AddRef()
7192     {
7193         return (BaseAddRefEnforceExternal());
7194     }
7195     ULONG STDMETHODCALLTYPE Release()
7196     {
7197         return (BaseReleaseEnforceExternal());
7198     }
7199
7200     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7201
7202
7203
7204     //-----------------------------------------------------------
7205     // ICorDebugRegisterSet
7206     // More extensive explanation are in Src/inc/CorDebug.idl
7207     //-----------------------------------------------------------
7208     COM_METHOD GetRegistersAvailable(ULONG64 *pAvailable);
7209
7210     COM_METHOD GetRegisters(ULONG64 mask,
7211                             ULONG32 regCount,
7212                             CORDB_REGISTER regBuffer[]);
7213     COM_METHOD SetRegisters( ULONG64 mask,
7214                              ULONG32 regCount,
7215                              CORDB_REGISTER regBuffer[])
7216     {
7217         LIMITED_METHOD_CONTRACT;
7218
7219         VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER,
7220                                          regCount, true, true);
7221
7222         return E_NOTIMPL;
7223     }
7224
7225     COM_METHOD GetThreadContext(ULONG32 contextSize, BYTE context[]);
7226
7227     // SetThreadContexthad a very problematic implementation in v1.1.
7228     // We've ripped it out in V2.0 and E_NOTIMPL it. See V1.1 sources for what it used to look like
7229     // in case we ever want to re-add it.
7230     // If we ever re-implement it consider the following:
7231     // - must fail on non-leaf frames (just check m_active).
7232     // - must make sure that GetThreadContext() is fully accurate. If we don't have SetThCtx, then
7233     //   GetThreadCtx bugs are much more benign.
7234     // - be sure to update any shared reg displays (what if a frame + chain have the same rd) and
7235     //   also update any cached contexts (such as CordbThread::m_context).
7236     // - be sure to honor the context flags and only setting what we can set.
7237     //
7238     // Friday, July 16, 2004. (This date will be useful for Source control history)
7239     COM_METHOD SetThreadContext(ULONG32 contextSize, BYTE context[])
7240     {
7241         return E_NOTIMPL;
7242     }
7243
7244     //-----------------------------------------------------------
7245     // ICorDebugRegisterSet2
7246     // More extensive explanation are in Src/inc/CorDebug.idl
7247     //-----------------------------------------------------------
7248     COM_METHOD GetRegistersAvailable(ULONG32 regCount,
7249                                      BYTE    pAvailable[]);
7250
7251     COM_METHOD GetRegisters(ULONG32 maskCount,
7252                             BYTE    mask[],
7253                             ULONG32 regCount,
7254                             CORDB_REGISTER regBuffer[]);
7255
7256     COM_METHOD SetRegisters(ULONG32 maskCount,
7257                             BYTE    mask[],
7258                             ULONG32 regCount,
7259                             CORDB_REGISTER regBuffer[])
7260     {
7261         LIMITED_METHOD_CONTRACT;
7262
7263         VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER,
7264                                          regCount, true, true);
7265
7266         return E_NOTIMPL;
7267     }
7268
7269 protected:
7270     // Platform specific helper for GetThreadContext.
7271     void InternalCopyRDToContext(DT_CONTEXT * pContext);
7272
7273     // Adapters to impl v2.0 interfaces on top of v1.0 interfaces.
7274     HRESULT GetRegistersAvailableAdapter(ULONG32 regCount, BYTE pAvailable[]);
7275     HRESULT GetRegistersAdapter(ULONG32 maskCount, BYTE mask[], ULONG32 regCount, CORDB_REGISTER regBuffer[]);
7276
7277
7278     // This CordbRegisterSet is responsible to free this memory if m_fTakeOwnershipOfDRD is true.  Otherwise,
7279     // this memory is freed by the CordbNativeFrame or CordbThread which creates this CordbRegisterSet.
7280     DebuggerREGDISPLAY  *m_rd;
7281     CordbThread         *m_thread;
7282     bool                m_active; // true if we're the leafmost register set.
7283     bool                m_quickUnwind;
7284
7285     // true if the CordbRegisterSet owns the DebuggerREGDISPLAY pointer and needs to free the memory
7286     bool                m_fTakeOwnershipOfDRD;      
7287 } ;
7288
7289
7290
7291
7292 /* ------------------------------------------------------------------------- *
7293  * JIT-IL Frame class
7294  * ------------------------------------------------------------------------- */
7295
7296 class CordbJITILFrame : public CordbBase, public ICorDebugILFrame, public ICorDebugILFrame2, public ICorDebugILFrame3, public ICorDebugILFrame4
7297 {
7298 public:
7299     CordbJITILFrame(CordbNativeFrame *    pNativeFrame,
7300                     CordbILCode *         pCode,
7301                     UINT_PTR              ip,
7302                     CorDebugMappingResult mapping,
7303                     GENERICS_TYPE_TOKEN   exactGenericArgsToken,
7304                     DWORD                 dwExactGenericArgsTokenIndex,
7305                     bool                  fVarArgFnx,
7306                     CordbReJitILCode *    pReJitCode);
7307     HRESULT Init();
7308     virtual ~CordbJITILFrame();
7309     virtual void Neuter();
7310
7311
7312 #ifdef _DEBUG
7313     virtual const char * DbgGetName() { return "CordbJITILFrame"; }
7314 #endif
7315
7316     //-----------------------------------------------------------
7317     // IUnknown
7318     //-----------------------------------------------------------
7319
7320     ULONG STDMETHODCALLTYPE AddRef()
7321     {
7322         return (BaseAddRef());
7323     }
7324     ULONG STDMETHODCALLTYPE Release()
7325     {
7326         return (BaseRelease());
7327     }
7328     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7329
7330     //-----------------------------------------------------------
7331     // ICorDebugFrame
7332     //-----------------------------------------------------------
7333
7334     COM_METHOD GetChain(ICorDebugChain **ppChain);
7335     COM_METHOD GetCode(ICorDebugCode **ppCode);
7336     COM_METHOD GetFunction(ICorDebugFunction **ppFunction);
7337     COM_METHOD GetFunctionToken(mdMethodDef *pToken);
7338     COM_METHOD GetStackRange(CORDB_ADDRESS *pStart, CORDB_ADDRESS *pEnd);
7339     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper);
7340     COM_METHOD GetCaller(ICorDebugFrame **ppFrame);
7341     COM_METHOD GetCallee(ICorDebugFrame **ppFrame);
7342
7343     //-----------------------------------------------------------
7344     // ICorDebugILFrame
7345     //-----------------------------------------------------------
7346
7347     COM_METHOD GetIP(ULONG32* pnOffset, CorDebugMappingResult *pMappingResult);
7348     COM_METHOD SetIP(ULONG32 nOffset);
7349     COM_METHOD EnumerateLocalVariables(ICorDebugValueEnum **ppValueEnum);
7350     COM_METHOD GetLocalVariable(DWORD dwIndex, ICorDebugValue **ppValue);
7351     COM_METHOD EnumerateArguments(ICorDebugValueEnum **ppValueEnum);
7352     COM_METHOD GetArgument(DWORD dwIndex, ICorDebugValue ** ppValue);
7353     COM_METHOD GetStackDepth(ULONG32 *pDepth);
7354     COM_METHOD GetStackValue(DWORD dwIndex, ICorDebugValue **ppValue);
7355     COM_METHOD CanSetIP(ULONG32 nOffset);
7356
7357     //-----------------------------------------------------------
7358     // ICorDebugILFrame2
7359     //-----------------------------------------------------------
7360
7361     // Called at an EnC remap opportunity to remap to the latest version of a function
7362     COM_METHOD RemapFunction(ULONG32 nOffset);
7363
7364     COM_METHOD EnumerateTypeParameters(ICorDebugTypeEnum **ppTyParEnum);
7365     
7366     //-----------------------------------------------------------
7367     // ICorDebugILFrame3
7368     //-----------------------------------------------------------
7369     
7370     COM_METHOD GetReturnValueForILOffset(ULONG32 ILoffset, ICorDebugValue** ppReturnValue);
7371
7372     //-----------------------------------------------------------
7373     // ICorDebugILFrame4
7374     //-----------------------------------------------------------
7375
7376     COM_METHOD EnumerateLocalVariablesEx(ILCodeKind flags, ICorDebugValueEnum **ppValueEnum);
7377     COM_METHOD GetLocalVariableEx(ILCodeKind flags, DWORD dwIndex, ICorDebugValue **ppValue);
7378     COM_METHOD GetCodeEx(ILCodeKind flags, ICorDebugCode **ppCode);
7379
7380     //-----------------------------------------------------------
7381     // Non-COM methods
7382     //-----------------------------------------------------------
7383
7384     CordbModule *GetModule();
7385
7386     HRESULT GetNativeVariable(CordbType *type,
7387                               const ICorDebugInfo::NativeVarInfo *pNativeVarInfo,
7388                               ICorDebugValue **ppValue);
7389
7390     CordbAppDomain *GetCurrentAppDomain();
7391
7392     CordbFunction *GetFunction();
7393
7394     // ILVariableToNative serves to let the frame intercept accesses
7395     // to var args variables.
7396     HRESULT ILVariableToNative(DWORD dwIndex,
7397                                const ICorDebugInfo::NativeVarInfo ** ppNativeInfo);
7398
7399     // Fills in our array of var args variables
7400     HRESULT FabricateNativeInfo(DWORD dwIndex,
7401                                 const ICorDebugInfo::NativeVarInfo ** ppNativeInfo);
7402
7403     HRESULT GetArgumentType(DWORD dwIndex,
7404                             CordbType ** ppResultType);
7405
7406     // load the generics type and method arguments into a cache
7407     void LoadGenericArgs();
7408
7409     HRESULT QueryInterfaceInternal(REFIID id, void** pInterface);
7410
7411     // Builds an generic Instaniation object from the mdClass and generic signature
7412     // for what we are calling into.
7413     static HRESULT BuildInstantiationForCallsite(CordbModule *pModule, NewArrayHolder<CordbType*> &types, Instantiation &inst, Instantiation *currentInstantiation, mdToken targetClass, SigParser funcGenerics);
7414
7415     CordbILCode* GetOriginalILCode();
7416     CordbReJitILCode* GetReJitILCode();
7417
7418 private:
7419     void    RefreshCachedVarArgSigParserIfNeeded();
7420
7421     // Worker function for GetReturnValueForILOffset.
7422     HRESULT GetReturnValueForILOffsetImpl(ULONG32 ILoffset, ICorDebugValue** ppReturnValue);
7423
7424     // Given pType, fills ppReturnValue with the correct value.
7425     HRESULT GetReturnValueForType(CordbType *pType, ICorDebugValue **ppReturnValue);
7426
7427     //-----------------------------------------------------------
7428     // Data members
7429     //-----------------------------------------------------------
7430
7431 public:
7432     // each CordbJITILFrame corresponds to exactly one CordbNativeFrame and one CordbILCode
7433     CordbNativeFrame * m_nativeFrame;
7434     CordbILCode *      m_ilCode;
7435
7436     // the IL offset and the mapping result for the offset
7437     UINT_PTR          m_ip;
7438     CorDebugMappingResult m_mapping;
7439
7440     // <vararg-specific fields>
7441
7442     // whether this is a vararg function
7443     bool              m_fVarArgFnx;
7444
7445     // the number of arguments, including the var args
7446     ULONG             m_allArgsCount;
7447
7448     // This byte array is used to store the signature for vararg methods.
7449     // It points to the underlying memory used by m_sigParserCached, and it enables us to easily delete
7450     // the underlying memory when the CordbJITILFrame is neutered.
7451     BYTE *            m_rgbSigParserBuf;
7452     
7453     // Do not mutate this, instead make copies of it and use the copies, that way we are guaranteed to 
7454     // start at the correct position in the signature each time.  
7455     // The underlying memory used for the signature in the SigParser must not be in the DAC cache.
7456     // Otherwise it may be flushed underneath us, and we would AV when we try to access it.
7457     SigParser         m_sigParserCached;
7458
7459     // the address of the first arg; only used for vararg functions
7460     CORDB_ADDRESS     m_FirstArgAddr;
7461
7462     // This is an array of variable information for the arguments.  
7463     // The variable information is fabricated by the RS.
7464     ICorDebugInfo::NativeVarInfo * m_rgNVI;
7465
7466     // </vararg-specific fields>
7467
7468     Instantiation     m_genericArgs;        // the generics type arguments
7469     BOOL              m_genericArgsLoaded;  // whether we have loaded and cached the generics type arguments
7470
7471     // An extra token to help fetch information about any generic
7472     // parameters passed to the method, perhaps dynamically.
7473     // This is the so-called generics type context/token.
7474     //
7475     // This token comes from the stackwalker and it may be NULL, in which case we need to retrieve the token 
7476     // ourselves using m_dwFrameParamsTokenIndex and the variable lifetime information.
7477     GENERICS_TYPE_TOKEN m_frameParamsToken;
7478
7479     // IL Variable index of the Generics Arg Token.
7480     DWORD               m_dwFrameParamsTokenIndex;
7481
7482     // if this frame is instrumented with rejit, this will point to the instrumented IL code
7483     RSSmartPtr<CordbReJitILCode> m_pReJitCode;
7484 };
7485
7486 /* ------------------------------------------------------------------------- *
7487  * Breakpoint class
7488  * ------------------------------------------------------------------------- */
7489
7490 enum CordbBreakpointType
7491 {
7492     CBT_FUNCTION,
7493     CBT_MODULE,
7494     CBT_VALUE
7495 };
7496
7497 class CordbBreakpoint : public CordbBase, public ICorDebugBreakpoint
7498 {
7499 public:
7500     CordbBreakpoint(CordbProcess * pProcess, CordbBreakpointType bpType);
7501     virtual void Neuter();
7502
7503 #ifdef _DEBUG
7504     virtual const char * DbgGetName() { return "CordbBreakpoint"; }
7505 #endif
7506
7507     //-----------------------------------------------------------
7508     // IUnknown
7509     //-----------------------------------------------------------
7510
7511     ULONG STDMETHODCALLTYPE AddRef()
7512     {
7513         return (BaseAddRef());
7514     }
7515     ULONG STDMETHODCALLTYPE Release()
7516     {
7517         return (BaseRelease());
7518     }
7519     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7520
7521     //-----------------------------------------------------------
7522     // ICorDebugBreakpoint
7523     //-----------------------------------------------------------
7524
7525     COM_METHOD BaseIsActive(BOOL *pbActive);
7526
7527     //-----------------------------------------------------------
7528     // Non-COM methods
7529     //-----------------------------------------------------------
7530     CordbBreakpointType GetBPType()
7531     {
7532         return m_type;
7533     }
7534
7535     virtual void Disconnect() {}
7536
7537     CordbAppDomain *GetAppDomain()
7538     {
7539         return m_pAppDomain;
7540     }
7541     //-----------------------------------------------------------
7542     // Data members
7543     //-----------------------------------------------------------
7544
7545 public:
7546     bool                m_active;
7547     CordbAppDomain *m_pAppDomain;
7548     CordbBreakpointType m_type;
7549 };
7550
7551 /* ------------------------------------------------------------------------- *
7552  * Function Breakpoint class
7553  * ------------------------------------------------------------------------- */
7554
7555 class CordbFunctionBreakpoint : public CordbBreakpoint,
7556                                 public ICorDebugFunctionBreakpoint
7557 {
7558 public:
7559     CordbFunctionBreakpoint(CordbCode *code, SIZE_T offset);
7560     ~CordbFunctionBreakpoint();
7561
7562     virtual void Neuter();
7563 #ifdef _DEBUG
7564     virtual const char * DbgGetName() { return "CordbFunctionBreakpoint"; }
7565 #endif
7566
7567
7568     //-----------------------------------------------------------
7569     // IUnknown
7570     //-----------------------------------------------------------
7571
7572     ULONG STDMETHODCALLTYPE AddRef()
7573     {
7574         return (BaseAddRef());
7575     }
7576     ULONG STDMETHODCALLTYPE Release()
7577     {
7578         return (BaseRelease());
7579     }
7580     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7581
7582     //-----------------------------------------------------------
7583     // ICorDebugBreakpoint
7584     //-----------------------------------------------------------
7585
7586     COM_METHOD GetFunction(ICorDebugFunction **ppFunction);
7587     COM_METHOD GetOffset(ULONG32 *pnOffset);
7588     COM_METHOD Activate(BOOL bActive);
7589     COM_METHOD IsActive(BOOL *pbActive)
7590     {
7591         VALIDATE_POINTER_TO_OBJECT(pbActive, BOOL *);
7592
7593         return BaseIsActive(pbActive);
7594     }
7595
7596     //-----------------------------------------------------------
7597     // Non-COM methods
7598     //-----------------------------------------------------------
7599
7600     void Disconnect();
7601
7602     //-----------------------------------------------------------
7603     // Convenience routines
7604     //-----------------------------------------------------------
7605
7606
7607     //-----------------------------------------------------------
7608     // Data members
7609     //-----------------------------------------------------------
7610
7611     // Get a point to the LS BP object.
7612     LSPTR_BREAKPOINT GetLsPtrBP();
7613 public:
7614
7615     // We need to have a strong pointer because we may access the m_code object after we're neutered.
7616     // @todo - use external pointer b/c Breakpoints aren't yet rooted, and so this reference could be
7617     // leaked.
7618     RSExtSmartPtr<CordbCode> m_code;
7619     SIZE_T          m_offset;
7620 };
7621
7622 /* ------------------------------------------------------------------------- *
7623  * Module Breakpoint class
7624  * ------------------------------------------------------------------------- */
7625
7626 class CordbModuleBreakpoint : public CordbBreakpoint,
7627                               public ICorDebugModuleBreakpoint
7628 {
7629 public:
7630     CordbModuleBreakpoint(CordbModule *pModule);
7631
7632
7633
7634 #ifdef _DEBUG
7635     virtual const char * DbgGetName() { return "CordbModuleBreakpoint"; }
7636 #endif
7637
7638
7639     //-----------------------------------------------------------
7640     // IUnknown
7641     //-----------------------------------------------------------
7642
7643     ULONG STDMETHODCALLTYPE AddRef()
7644     {
7645         return (BaseAddRef());
7646     }
7647     ULONG STDMETHODCALLTYPE Release()
7648     {
7649         return (BaseRelease());
7650     }
7651     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7652
7653     //-----------------------------------------------------------
7654     // ICorDebugModuleBreakpoint
7655     //-----------------------------------------------------------
7656
7657     COM_METHOD GetModule(ICorDebugModule **ppModule);
7658     COM_METHOD Activate(BOOL bActive);
7659     COM_METHOD IsActive(BOOL *pbActive)
7660     {
7661         VALIDATE_POINTER_TO_OBJECT(pbActive, BOOL *);
7662
7663         return BaseIsActive(pbActive);
7664     }
7665
7666     //-----------------------------------------------------------
7667     // Non-COM methods
7668     //-----------------------------------------------------------
7669
7670     void Disconnect();
7671
7672 public:
7673     CordbModule       *m_module;
7674 };
7675
7676
7677 /* ------------------------------------------------------------------------- *
7678  * Stepper class
7679  * ------------------------------------------------------------------------- */
7680
7681 class CordbStepper : public CordbBase, public ICorDebugStepper, public ICorDebugStepper2
7682 {
7683 public:
7684     CordbStepper(CordbThread *thread, CordbFrame *frame = NULL);
7685
7686
7687
7688 #ifdef _DEBUG
7689     virtual const char * DbgGetName() { return "CordbStepper"; }
7690 #endif
7691
7692
7693     //-----------------------------------------------------------
7694     // IUnknown
7695     //-----------------------------------------------------------
7696
7697     ULONG STDMETHODCALLTYPE AddRef()
7698     {
7699         return (BaseAddRef());
7700     }
7701     ULONG STDMETHODCALLTYPE Release()
7702     {
7703         return (BaseRelease());
7704     }
7705     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7706
7707     //-----------------------------------------------------------
7708     // ICorDebugStepper
7709     //-----------------------------------------------------------
7710
7711     COM_METHOD IsActive(BOOL *pbActive);
7712     COM_METHOD Deactivate();
7713     COM_METHOD SetInterceptMask(CorDebugIntercept mask);
7714     COM_METHOD SetUnmappedStopMask(CorDebugUnmappedStop mask);
7715     COM_METHOD Step(BOOL bStepIn);
7716     COM_METHOD StepRange(BOOL bStepIn,
7717                          COR_DEBUG_STEP_RANGE ranges[],
7718                          ULONG32 cRangeCount);
7719     COM_METHOD StepOut();
7720     COM_METHOD SetRangeIL(BOOL bIL);
7721
7722     //-----------------------------------------------------------
7723     // ICorDebugStepper2
7724     //-----------------------------------------------------------
7725     COM_METHOD SetJMC(BOOL fIsJMCStepper);
7726
7727     //-----------------------------------------------------------
7728     // Convenience routines
7729     //-----------------------------------------------------------
7730
7731     CordbAppDomain *GetAppDomain()
7732     {
7733         return (m_thread->GetAppDomain());
7734     }
7735
7736     LSPTR_STEPPER GetLsPtrStepper();
7737
7738     //-----------------------------------------------------------
7739     // Data members
7740     //-----------------------------------------------------------
7741
7742     CordbThread     *m_thread;
7743     CordbFrame      *m_frame;
7744     REMOTE_PTR      m_stepperToken;
7745     bool            m_active;
7746     bool            m_rangeIL;
7747     bool            m_fIsJMCStepper;
7748     CorDebugUnmappedStop m_rgfMappingStop;
7749     CorDebugIntercept m_rgfInterceptStop;
7750 };
7751
7752 #define REG_SIZE sizeof(SIZE_T)
7753
7754 // class RegisterInfo: encapsulates information necessary to identify and access a specific register in a
7755 // register display
7756 class RegisterInfo
7757
7758 public:
7759     // constructor for an instance of RegisterInfo
7760     // Arguments:
7761     //     input:  kNumber - value from CorDebugRegister to identify the register
7762     //             addr    - address in remote register display that holds the value
7763     //     output: no out parameters, but this instance of RegisterInfo has been initialized
7764     RegisterInfo(const CorDebugRegister kNumber, CORDB_ADDRESS addr, SIZE_T value):       
7765         m_kRegNumber((CorDebugRegister)kNumber),
7766         m_regAddr(addr),
7767         m_regValue(value)
7768     {};
7769
7770
7771     // copy constructor
7772     // Arguments:
7773     //     input:  regInfo - register info from which the values for this instance will come
7774     //     output: no out parameters, but this instance of RegisterInfo has been initialized
7775     RegisterInfo(const RegisterInfo * pRegInfo):
7776         m_kRegNumber(pRegInfo->m_kRegNumber),
7777         m_regAddr(pRegInfo->m_regAddr),
7778         m_regValue(pRegInfo->m_regValue)
7779     {};
7780
7781
7782     //-------------------------------------
7783     // data members
7784     //-------------------------------------    
7785
7786     // enumeration value to identify the register, e.g., REGISTER_X86_EAX, or REGISTER_AMD64_XMM0
7787     CorDebugRegister  m_kRegNumber;
7788
7789     // address in a context or frame register display of the register value
7790     CORDB_ADDRESS     m_regAddr;
7791
7792     // the actual value of the register
7793     SIZE_T            m_regValue;
7794 }; // class RegisterInfo
7795
7796 // class EnregisteredValueHome: abstract class to encapsulate basic information for a register value, and
7797 // serve as a base class for values residing in register-based locations, such as a single register, a
7798 // register pair, or a register and memory location.
7799 class EnregisteredValueHome
7800 {
7801 public:
7802
7803     // constructor to initialize an instance of EnregisteredValueHome
7804     EnregisteredValueHome(const CordbNativeFrame * pFrame);
7805
7806     virtual ~EnregisteredValueHome() {}
7807
7808     // virtual "copy constructor" to make a copy of "this" to be owned by a different instance of
7809     // Cordb*Value. If an instance of CordbVCObjectValue represents an enregistered value class, it means
7810     // there is a single field. This implies that the register for the CordbVCObject instance is the same as
7811     // the register for its field. When we create a Cordb*Value to represent this field, we need to make a
7812     // copy of the EnregisteredValueHome belonging to the CordbVCObject instance to become the
7813     // EnregisteredValueHome of the Cord*Value representing the field.
7814     // returns:
7815     //   a new cloned copy of this object, allocated on the heap.
7816     //   Caller is responsible for deleting the  memory (using the standard delete operator).
7817     // note:
7818     //    C++ allows derived implementations to differ on return type, thus allowing
7819     //    derived impls to return the cloned copy as its actual derived type, and not just as a base type.
7820
7821
7822     virtual
7823     EnregisteredValueHome * Clone() const = 0;
7824
7825     // set a remote enregistered location to a new value
7826     // Arguments:
7827     //     input:  pNewValue - buffer containing the new value along with its size
7828     //             pContext  - context from which the value comes
7829     //             fIsSigned - indicates whether the value is signed or not. The value provided may be smaller than
7830     //                         a register, in which case we'll need to extend it to a full register width. To do this
7831     //                         correctly, we need to know whether to sign extend or zero extend. Currently, only
7832     //                         the RegValueHome virtual function uses this, but we may need it if we introduce
7833     //                         types that don't completely occupy the size of two registers.  
7834     //     output: updates the remote enregistered value on success            
7835     // Note: Throws E_FAIL for invalid input or various HRESULTs from an 
7836     //                         unsuccessful call to WriteProcessMemory
7837     virtual
7838     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned) = 0;
7839
7840     // Gets an enregistered value and returns it to the caller
7841     // Arguments: 
7842     //     input:  pValueOutBuffer - buffer in which to return the value, along with its size
7843     //     output: pValueOutBuffer - filled with the value 
7844     // Note: Throws E_NOTIMPL for attempts to get an enregistered value for a float register
7845     // (implementation for derived class FloatRegValueHome)
7846     virtual
7847     void GetEnregisteredValue(MemoryRange valueOutBuffer) = 0;
7848
7849     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
7850     // instance of a derived class of EnregisteredValueHome
7851     // Arguments: input:  none--uses fields of "this"
7852     //            output: pRegAddr - address of an instance of RemoteAddress with field values set to corresponding 
7853     //            field values of "this"
7854     virtual
7855     void CopyToIPCEType(RemoteAddress * pRegAddr) = 0;
7856
7857     // accessor
7858     const CordbNativeFrame * GetFrame() const { return m_pFrame; };
7859
7860     //-------------------------------------
7861     // data members
7862     //------------------------------------- 
7863 protected:    
7864     // The frame on which the value resides
7865     const CordbNativeFrame * m_pFrame;
7866
7867 }; // class EnregisteredValueHome
7868
7869 typedef NewHolder<EnregisteredValueHome> EnregisteredValueHomeHolder;
7870
7871 // class RegValueHome: encapsulates basic information for a value that resides in a single register
7872 // and serves as a base class for values residing in a register pair.
7873 class RegValueHome: public EnregisteredValueHome
7874 {
7875 public:
7876
7877     // initializing constructor 
7878     // Arguments:
7879     //     input:  pFrame  - frame to which the value belongs
7880     //             regNum  - enumeration value corresponding to the particular hardware register in
7881     //                       which the value resides
7882     //             regAddr - remote address within a register display (in a context or frame) of the
7883     //                       register value
7884     //     output: no out parameters, but the instance has been initialized
7885     RegValueHome(const CordbNativeFrame *  pFrame, 
7886                  CorDebugRegister          regNum):
7887         EnregisteredValueHome(pFrame),
7888         m_reg1Info(regNum, 
7889                    pFrame->GetLeftSideAddressOfRegister(regNum), 
7890                    *(pFrame->GetAddressOfRegister(regNum)))
7891     {};
7892
7893     // copy constructor
7894     // Arguments:
7895     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
7896     //                              instance will come
7897     //     output: no out parameters, but the instance has been initialized
7898     RegValueHome(const RegValueHome * pRemoteRegAddr):
7899         EnregisteredValueHome(pRemoteRegAddr->m_pFrame),
7900         m_reg1Info(pRemoteRegAddr->m_reg1Info)
7901     {};
7902
7903     // make a copy of this instance of RegValueHome
7904     virtual
7905     RegValueHome * Clone() const { return new RegValueHome(*this); };
7906
7907     // updates a register in a given context, and in the regdisplay of a given frame.
7908     void SetContextRegister(DT_CONTEXT *     pContext,
7909                             CorDebugRegister regNum,
7910                             SIZE_T           newVal);
7911
7912     // set the value of a remote enregistered value
7913     virtual
7914     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
7915
7916     // Gets an enregistered value and returns it to the caller
7917     virtual
7918     void GetEnregisteredValue(MemoryRange valueOutBuffer);
7919     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
7920     // instance of a derived class of RegValueHome
7921     virtual
7922     void CopyToIPCEType(RemoteAddress * pRegAddr);
7923
7924     //-------------------------------------
7925     // data members
7926     //------------------------------------- 
7927 protected:       
7928     // The information for the register in which the value resides. 
7929     const RegisterInfo               m_reg1Info;
7930 }; // class RegValueHome
7931
7932 // class RegRegValueHome
7933 // derived class to add a second register for values that live in a pair of registers
7934 class RegRegValueHome: public RegValueHome
7935 {
7936 public:
7937     // initializing constructor 
7938     // Arguments:
7939     //     input:  pFrame   - frame to which the value belongs
7940     //             reg1Num  - enumeration value corresponding to the first particular hardware register in
7941     //                        which the value resides
7942     //             reg1Addr - remote address within a register display (in a context or frame) of the
7943     //                        first register
7944     //             reg2Num  - enumeration value corresponding to the second particular hardware register in
7945     //                        which the value resides
7946     //             reg2Addr - remote address within a register display (in a context or frame) of the
7947     //                        second register
7948     //     output: no out parameters, but the instance has been initialized
7949     RegRegValueHome(const CordbNativeFrame * pFrame, 
7950                     CorDebugRegister         reg1Num, 
7951                     CorDebugRegister         reg2Num):
7952         RegValueHome(pFrame, reg1Num),
7953         m_reg2Info(reg2Num, 
7954                    pFrame->GetLeftSideAddressOfRegister(reg2Num),
7955                    *(pFrame->GetAddressOfRegister(reg2Num)))
7956     {};
7957
7958     // copy constructor
7959     // Arguments:
7960     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
7961     //                              instance will come
7962     //     output: no out parameters, but the instance has been initialized
7963     RegRegValueHome(const RegRegValueHome * pRemoteRegAddr):
7964         RegValueHome(pRemoteRegAddr),
7965         m_reg2Info(pRemoteRegAddr->m_reg2Info)
7966     {};
7967
7968     // make a copy of this instance of RegRegValueHome
7969     virtual
7970     RegRegValueHome * Clone() const { return new RegRegValueHome(*this); };
7971
7972     // set the value of a remote enregistered value
7973     virtual
7974     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
7975
7976     // Gets an enregistered value and returns it to the caller
7977     virtual
7978     void GetEnregisteredValue(MemoryRange valueOutBuffer);
7979
7980     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
7981     // instance of a derived class of EnregisteredValueHome
7982     void CopyToIPCEType(RemoteAddress * pRegAddr);
7983
7984     //-------------------------------------
7985     // data members
7986     //------------------------------------- 
7987     
7988 protected:    
7989     // The information for the second of two registers in which the value resides. 
7990     const RegisterInfo               m_reg2Info;
7991 }; // class RegRegValueHome
7992
7993 // class RegAndMemBaseValueHome 
7994 // derived from RegValueHome, this class is also a base class for RegMemValueHome
7995 // and MemRegValueHome, which add a memory location for reg-mem or mem-reg values
7996 class RegAndMemBaseValueHome: public RegValueHome
7997 {
7998 public:
7999     // initializing constructor 
8000     // Arguments:
8001     //     input:  pFrame   - frame to which the value belongs
8002     //             reg1Num  - enumeration value corresponding to the first particular hardware register in
8003     //                        which the value resides
8004     //             reg1Addr - remote address within a register display (in a context or frame) of the
8005     //                        register component of the value
8006     //             memAddr  - remote address for the memory component of the value
8007     //     output: no out parameters, but the instance has been initialized
8008     RegAndMemBaseValueHome(const CordbNativeFrame *      pFrame, 
8009                            CorDebugRegister              reg1Num, 
8010                            CORDB_ADDRESS                 memAddr):
8011         RegValueHome(pFrame, reg1Num),
8012         m_memAddr(memAddr) 
8013     {};
8014
8015     // copy constructor
8016     // Arguments:
8017     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
8018     //                              instance will come
8019     //     output: no out parameters, but the instance has been initialized
8020     RegAndMemBaseValueHome(const RegAndMemBaseValueHome * pRemoteRegAddr):
8021         RegValueHome(pRemoteRegAddr), 
8022         m_memAddr()
8023     {};
8024
8025     // make a copy of this instance of RegRegValueHome
8026     virtual
8027     RegAndMemBaseValueHome * Clone() const = 0;
8028
8029     // set the value of a remote enregistered value
8030     virtual
8031     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * DT_pContext, bool fIsSigned) = 0;
8032
8033     // Gets an enregistered value and returns it to the caller
8034     virtual 
8035     void GetEnregisteredValue(MemoryRange valueOutBuffer) = 0;
8036
8037     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
8038     // instance of a derived class of EnregisteredValueHome
8039     virtual
8040     void CopyToIPCEType(RemoteAddress * pRegAddr) = 0;
8041
8042     //-------------------------------------
8043     // data members
8044     //------------------------------------- 
8045     
8046 protected:    
8047     // remote address for the memory component of the value
8048     CORDB_ADDRESS m_memAddr;
8049
8050 }; // class RegAndMemBaseValueHome;
8051
8052 // class RegMemValueHome
8053 // type derived from abstract class RegAndMemBaseValueHome to represent a Register/Memory location where the 
8054 // high order part of the value is kept in a register, and the low order part is kept in memory
8055 class RegMemValueHome: public RegAndMemBaseValueHome
8056 {
8057 public:
8058
8059     // initializing constructor 
8060     // Arguments:
8061     //     input:  pFrame   - frame to which the value belongs
8062     //             reg1Num  - enumeration value corresponding to the first particular hardware register in
8063     //                        which the value resides
8064     //             reg1Addr - remote address within a register display (in a context or frame) of the
8065     //                        register component of the value
8066     //             memAddr  - remote address for the memory component of the value
8067     //     output: no out parameters, but the instance has been initialized
8068     RegMemValueHome(const CordbNativeFrame *      pFrame, 
8069                     CorDebugRegister              reg1Num, 
8070                     CORDB_ADDRESS                 memAddr):
8071        RegAndMemBaseValueHome(pFrame, reg1Num, memAddr)
8072    {};
8073
8074     // copy constructor
8075     // Arguments:
8076     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
8077     //                              instance will come
8078     //     output: no out parameters, but the instance has been initialized
8079     RegMemValueHome(const RegMemValueHome * pRemoteRegAddr):
8080         RegAndMemBaseValueHome(pRemoteRegAddr)
8081     {};
8082
8083     // make a copy of this instance of RegMemValueHome
8084     virtual
8085     RegMemValueHome * Clone() const { return new RegMemValueHome(*this); };
8086
8087     // set the value of a remote enregistered value
8088     virtual
8089     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
8090
8091     // Gets an enregistered value and returns it to the caller
8092     virtual
8093     void GetEnregisteredValue(MemoryRange valueOutBuffer);
8094
8095     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
8096     // instance of a derived class of EnregisteredValueHome
8097     virtual
8098     void CopyToIPCEType(RemoteAddress * pRegAddr);
8099
8100 }; // class RegMemValueHome;
8101
8102 // class MemRegValueHome
8103 // type derived from abstract class RegAndMemBaseValueHome to represent a Register/Memory location where the 
8104 // low order part of the value is kept in a register, and the high order part is kept in memory
8105 class MemRegValueHome: public RegAndMemBaseValueHome
8106 {
8107 public:
8108
8109     // initializing constructor 
8110     // Arguments:
8111     //     input:  pFrame   - frame to which the value belongs
8112     //             reg1Num  - enumeration value corresponding to the first particular hardware register in
8113     //                        which the value resides
8114     //             reg1Addr - remote address within a register display (in a context or frame) of the
8115     //                        register component of the value
8116     //             memAddr  - remote address for the memory component of the value
8117     //     output: no out parameters, but the instance has been initialized
8118     MemRegValueHome(const CordbNativeFrame *      pFrame, 
8119                     CorDebugRegister              reg1Num, 
8120                     CORDB_ADDRESS                 memAddr):
8121        RegAndMemBaseValueHome(pFrame, reg1Num, memAddr)
8122    {};
8123
8124     // copy constructor
8125     // Arguments:
8126     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
8127     //                              instance will come
8128     //     output: no out parameters, but the instance has been initialized
8129     MemRegValueHome(const MemRegValueHome * pRemoteRegAddr):
8130         RegAndMemBaseValueHome(pRemoteRegAddr)
8131     {};
8132
8133     // make a copy of this instance of MemRegValueHome
8134     virtual
8135     MemRegValueHome * Clone() const { return new MemRegValueHome(*this); };
8136
8137     // set the value of a remote enregistered value
8138     virtual
8139     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
8140
8141     // Gets an enregistered value and returns it to the caller
8142     virtual
8143     void GetEnregisteredValue(MemoryRange valueOutBuffer);
8144
8145     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
8146     // instance of a derived class of EnregisteredValueHome
8147     virtual
8148     void CopyToIPCEType(RemoteAddress * pRegAddr);
8149
8150 }; // class MemRegValueHome;
8151
8152 // class FloatRegValueHome
8153 // derived class to add an index into the FP register stack for a floating point value
8154 class FloatRegValueHome: public EnregisteredValueHome
8155 {
8156 public:
8157     // initializing constructor 
8158     // Arguments:
8159     //     input:  pFrame - frame to which the value belongs
8160     //             index  - index into the floating point stack where the value resides
8161     //     output: no out parameters, but the instance has been initialized
8162     FloatRegValueHome(const CordbNativeFrame *      pFrame,
8163                       DWORD                         index):
8164         EnregisteredValueHome(pFrame),
8165         m_floatIndex(index)
8166     {};
8167
8168     // copy constructor
8169     // Arguments:
8170     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
8171     //                              instance will come
8172     //     output: no out parameters, but the instance has been initialized
8173     FloatRegValueHome(const FloatRegValueHome * pRemoteRegAddr):
8174         EnregisteredValueHome(pRemoteRegAddr->m_pFrame),
8175         m_floatIndex(pRemoteRegAddr->m_floatIndex)
8176     {};
8177
8178     // make a copy of this instance of FloatRegValueHome
8179     virtual
8180     FloatRegValueHome * Clone() const { return new FloatRegValueHome(*this); };
8181
8182     // set the value of a remote enregistered value
8183     virtual
8184     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
8185
8186     // Gets an enregistered value and returns it to the caller
8187     virtual
8188     void GetEnregisteredValue(MemoryRange valueOutBuffer);
8189
8190     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
8191     // instance of a derived class of EnregisteredValueHome
8192     virtual
8193     void CopyToIPCEType(RemoteAddress * pRegAddr);
8194
8195     //-------------------------------------
8196     // data members
8197     //------------------------------------- 
8198     
8199 protected:    
8200     // index into the FP registers for the register in which the floating point value resides
8201     const DWORD            m_floatIndex;
8202  }; // class FloatRegValueHome
8203
8204 // ----------------------------------------------------------------------------
8205 // Type hierarchy for value locations
8206 //                                               ValueHome 
8207 //                                                 | | |
8208 //                           ------------------  |  -------------------
8209 //                      |                    |                     |
8210 //              RemoteValueHome      RegisterValueHome       HandleValueHome
8211 //                 |       |                       
8212 //         --------         -------                      
8213 //        |                            |                    
8214 // VCRemoteValueHome      RefRemoteValueHome                  
8215 // 
8216 // ValueHome:           abstract base class, provides remote read and write utilities
8217 // RemoteValueHome:     used for CordbObjectValue, CordbArrayValue, and CordbBoxValue instances,
8218 //                      which have only remote locations, and for other ICDValues with a remote address
8219 // RegisterValueHome:   used for CordbGenericValue and CordbReferenceValue instances with 
8220 //                      only a register location            
8221 // HandleValueHome:     used for CordbReferenceValue instances with only an object handle 
8222 // VCRemoteValueHome:   used for CordbVCObjectValue instances to supply special operation CreateInternalValue for 
8223 //                      value class objects with only a remote location
8224 // RefRemoteValueHome:  used for CordbReferenceValue instances with only a remote location
8225 // 
8226 // In addition, we have a special type for the ValueHome field for CordbReferenceValue instances:
8227 // RefValueHome. This will have a field of type ValueHome and will implement extra operations only relevant
8228 // for object references.
8229 //                                     
8230 // ----------------------------------------------------------------------------
8231 // 
8232 class ValueHome
8233 {
8234 public:
8235     ValueHome(CordbProcess * pProcess):
8236       m_pProcess(pProcess) { _ASSERTE(pProcess != NULL); };
8237
8238     virtual
8239     ~ValueHome() {}
8240  
8241     // releases resources as necessary
8242     virtual
8243     void Clear() = 0;
8244
8245     // gets the remote address for the value or returns NULL if none exists
8246     virtual
8247         CORDB_ADDRESS GetAddress() = 0;
8248
8249     // Gets a value and returns it in dest
8250     // Argument: 
8251     //     input:  none (uses fields of the instance)
8252     //     output: dest - buffer containing the value retrieved as long as the returned HRESULT doesn't
8253     //     indicate an error. 
8254     // Note: Throws errors from read process memory operation or GetThreadContext operation
8255     virtual
8256     void GetValue(MemoryRange dest) = 0;
8257
8258     // Sets a location to the value provided in src
8259     // Arguments:
8260     //     input:  src -   buffer containing the new value to be set--memory for this buffer is owned by the caller
8261     //             pType - type information about the value
8262     //     output: none, but on success, changes m_remoteValue to hold the new value
8263     // Note: Throws errors from SafeWriteBuffer 
8264     virtual 
8265     void SetValue(MemoryRange src, CordbType * pType) = 0;
8266
8267     // creates an ICDValue for a field or array element or for the value type of a boxed object
8268     // Arguments: 
8269     //     input:  pType        - type of the internal value
8270     //             offset       - offset to the internal value
8271     //             localAddress - address of thelogical buffer within the parent class' local cached  
8272     //                            copy that holds the internal element
8273     //             size         - size of the internal value
8274     //    output:  ppValue      - the newly created ICDValue instance 
8275     // Note: Throws for a variety of possible failures: OOM, E_FAIL, errors from 
8276     //               ReadProcessMemory.
8277     virtual
8278     void CreateInternalValue(CordbType *       pType,
8279                              SIZE_T            offset,
8280                              void *            localAddress,
8281                              ULONG32           size,
8282                              ICorDebugValue ** ppValue) = 0;
8283
8284     // Gets the value of a field or element of an existing ICDValue instance and returns it in dest
8285     // Arguments
8286     //     input:  offset - offset within the value to the internal field or element
8287     //     output: dest   - buffer to hold the value--memory for this buffer is owned by the caller
8288     // Note: Throws process memory write errors
8289     virtual
8290     void GetInternalValue(MemoryRange dest, SIZE_T offset) = 0;
8291
8292     // copies register information from this to a RemoteAddress instance for FuncEval
8293     // Arguments:
8294     //     output: pRegAddr - copy of information in m_pRemoteRegAddr, converted to 
8295     //                        an instance of RemoteAddress
8296     virtual                        
8297     void CopyToIPCEType(RemoteAddress * pRegAddr) = 0;
8298
8299 private:
8300     // unimplemented copy constructor to prevent passing by value
8301     ValueHome(ValueHome * pValHome);
8302
8303 protected:
8304     // --------------
8305     // data member
8306     // --------------
8307    CordbProcess * m_pProcess;
8308 }; // class ValueHome
8309
8310 // ============================================================================
8311 // RemoteValueHome class
8312 // ============================================================================
8313 // to be used for CordbObjectValue, CordbArrayValue, and CordbBoxValue, none of which ever have anything but
8314 // a remote address
8315 class RemoteValueHome: public ValueHome
8316 {
8317 public:
8318     // constructor
8319     // Note: It's possible that remoteValue.pAddress may be NULL--FuncEval makes
8320     // empty GenericValues for literals in which case we would have neither a remote address nor a
8321     // register address
8322     RemoteValueHome(CordbProcess * pProcess, TargetBuffer remoteValue);
8323     
8324     // gets the remote address for the value
8325     virtual
8326     CORDB_ADDRESS GetAddress() { return m_remoteValue.pAddress; };
8327
8328     // releases resources as necessary
8329     virtual
8330     void Clear() {};
8331
8332     // Gets a value and returns it in dest
8333     virtual
8334     void GetValue(MemoryRange dest);
8335
8336     // Sets a location to the value provided in src
8337     virtual 
8338     void SetValue(MemoryRange src, CordbType * pType);
8339
8340     // creates an ICDValue for a field or array element or for the value type of a boxed object
8341     virtual
8342     void CreateInternalValue(CordbType *       pType,
8343                                 SIZE_T            offset,
8344                                 void *            localAddress,
8345                                 ULONG32           size,
8346                                 ICorDebugValue ** ppValue);
8347
8348     // Gets the value of a field or element of an existing ICDValue instance and returns it in dest
8349     virtual
8350     void GetInternalValue(MemoryRange dest, SIZE_T offset);
8351
8352     // copies register information from this to a RemoteAddress instance for FuncEval
8353     virtual
8354     void CopyToIPCEType(RemoteAddress * pRegAddr);
8355
8356
8357     // ----------------
8358     // data member
8359     // ----------------
8360     
8361 protected:
8362     TargetBuffer  m_remoteValue;
8363 }; // class RemoteValueHome
8364
8365 // ============================================================================
8366 // RegisterValueHome class 
8367 // ============================================================================
8368 // for values that may either have a remote location or be enregistered--
8369 // to be used for CordbGenericValue, and as base for CordbVCObjectValue and CordbReferenceValue
8370 class RegisterValueHome: public ValueHome
8371 {
8372 public:
8373     // constructor
8374     RegisterValueHome(CordbProcess *                pProcess, 
8375                       EnregisteredValueHomeHolder * ppRemoteRegAddr);
8376
8377     // clean up resources
8378     virtual
8379     void Clear();
8380
8381     // gets the remote address for the value or returns NULL if none exists
8382     virtual
8383     CORDB_ADDRESS GetAddress() { return NULL; };
8384
8385     // Gets a value and returns it in dest
8386     virtual
8387     void GetValue(MemoryRange dest);
8388     
8389     // Sets a location to the value provided in src
8390     virtual
8391     void SetValue(MemoryRange src, CordbType * pType);
8392
8393     // creates an ICDValue for a field or array element or for the value type of a boxed object
8394     virtual
8395     void CreateInternalValue(CordbType *       pType,
8396                              SIZE_T            offset,
8397                              void *            localAddress,
8398                              ULONG32           size,
8399                              ICorDebugValue ** ppValue);
8400
8401     // Gets the value of a field or element of an existing ICDValue instance and returns it in dest
8402     virtual
8403     void GetInternalValue(MemoryRange dest, SIZE_T offset);
8404
8405     // copies the register information from this to a RemoteAddress instance 
8406     virtual
8407     void CopyToIPCEType(RemoteAddress * pRegAddr);
8408
8409 protected:
8410
8411     // sets a remote enregistered location to a new value
8412     void SetEnregisteredValue(MemoryRange src, bool fIsSigned);
8413     
8414     // gets a value from an enregistered location
8415     void GetEnregisteredValue(MemoryRange dest); 
8416
8417     bool IsSigned(CorElementType elementType);
8418
8419     // ----------------
8420     // data member
8421     // ----------------
8422
8423 protected:
8424     // Left Side register location info for various kinds of (partly) enregistered values.
8425     EnregisteredValueHome * m_pRemoteRegAddr; 
8426
8427 }; // class RegisterValueHome
8428
8429 // ============================================================================
8430 // HandleValueHome class
8431 // ============================================================================
8432
8433 class HandleValueHome: public ValueHome
8434 {
8435 public:
8436     // constructor
8437     // Arguments:
8438     //     input:  pProcess   -  process to which the value belongs
8439     //             vmObjHandle - objectHandle holding the object address
8440     HandleValueHome(CordbProcess * pProcess, VMPTR_OBJECTHANDLE vmObjHandle):
8441         ValueHome(pProcess),
8442         m_vmObjectHandle(vmObjHandle) {};
8443
8444     // releases resources as necessary   
8445     virtual
8446     void Clear() {};
8447
8448     // gets the remote address for the value or returns NULL if none exists
8449     virtual
8450     CORDB_ADDRESS GetAddress();
8451
8452     // Gets a value and returns it in dest
8453     virtual
8454     void GetValue(MemoryRange dest);
8455     
8456     // Sets a location to the value provided in src
8457     virtual
8458     void SetValue(MemoryRange src, CordbType * pType);
8459
8460     // creates an ICDValue for a field or array element or for the value type of a boxed object
8461     virtual
8462     void CreateInternalValue(CordbType *       pType,
8463                              SIZE_T            offset,
8464                              void *            localAddress,
8465                              ULONG32           size,
8466                              ICorDebugValue ** ppValue);
8467
8468     // Gets the value of a field or element of an existing ICDValue instance and returns it in dest
8469     virtual
8470     void GetInternalValue(MemoryRange dest, SIZE_T offset);
8471
8472     // copies the register information from this to a RemoteAddress instance 
8473     virtual
8474     void CopyToIPCEType(RemoteAddress * pRegAddr);
8475
8476     // ----------------
8477     // data member
8478     // ----------------
8479 private:
8480     VMPTR_OBJECTHANDLE m_vmObjectHandle;
8481 }; // class HandleValueHome;
8482
8483 // ============================================================================
8484 // VCRemoteValueHome class
8485 // ============================================================================
8486 // used only for CordbVCObjectValue
8487 class VCRemoteValueHome: public RemoteValueHome
8488 {
8489 public:
8490     // constructor
8491     VCRemoteValueHome(CordbProcess * pProcess, 
8492                       TargetBuffer   remoteValue):
8493         RemoteValueHome(pProcess, remoteValue) {};
8494
8495     // Sets a location to the value provided in src 
8496     virtual
8497     void SetValue(MemoryRange src, CordbType * pType);
8498
8499 }; // class VCRemoteValueHome
8500
8501 // ============================================================================
8502 // RefRemoteValueHome class
8503 // ============================================================================
8504
8505 // used only for CordbReferenceValue
8506 class RefRemoteValueHome: public RemoteValueHome
8507 {
8508 public:
8509     // constructor
8510     // Arguments
8511     RefRemoteValueHome(CordbProcess *                pProcess, 
8512                        TargetBuffer                  remoteValue);
8513
8514     // Sets a location to the value provided in src
8515     virtual
8516     void SetValue(MemoryRange src, CordbType * pType);
8517
8518 }; // class RefRemoteValueHome
8519
8520 // ============================================================================
8521 // RefValueHome class
8522 // ============================================================================
8523
8524 // abstract superclass for derivations RefRemoteValueHome and RefRegValueHome
8525 class RefValueHome
8526 {
8527 public:
8528     // constructor
8529     RefValueHome() { m_pHome = NULL; m_fNullObjHandle = true; };
8530
8531     // constructor
8532     RefValueHome(CordbProcess *                pProcess, 
8533                  TargetBuffer                  remoteValue,
8534                  EnregisteredValueHomeHolder * ppRemoteRegAddr,
8535                  VMPTR_OBJECTHANDLE            vmObjHandle);
8536
8537     // indicates whether the object handle is null
8538     bool ObjHandleIsNull() { return m_fNullObjHandle; };
8539     void SetObjHandleFlag(bool isNull) { m_fNullObjHandle = isNull; };
8540
8541     // ----------------
8542     // data members 
8543     // ----------------
8544     // appropriate instantiation of ValueHome 
8545     ValueHome * m_pHome;
8546
8547 private:
8548     // true iff m_pHome is an instantiation of RemoteValueHome or RegisterValueHome  
8549     bool m_fNullObjHandle;
8550 }; // class RefValueHome
8551
8552 typedef enum {kUnboxed, kBoxed} BoxedValue;
8553 #define EMPTY_BUFFER TargetBuffer(PTR_TO_CORDB_ADDRESS((void *)NULL), 0)
8554
8555 /* ------------------------------------------------------------------------- *
8556  * Variable Home class
8557  * ------------------------------------------------------------------------- */
8558 class CordbVariableHome : public CordbBase, public ICorDebugVariableHome
8559 {
8560 public:
8561     CordbVariableHome(CordbNativeCode *pCode,
8562                       const ICorDebugInfo::NativeVarInfo nativeVarInfo,
8563                       BOOL isLoc,
8564                       ULONG index);
8565     ~CordbVariableHome();
8566     virtual void Neuter();
8567
8568 #ifdef _DEBUG
8569     virtual const char * DbgGetName() { return "CordbVariableHome"; }
8570 #endif
8571     
8572     //-----------------------------------------------------------
8573     // IUnknown
8574     //-----------------------------------------------------------
8575     ULONG STDMETHODCALLTYPE AddRef()
8576     {
8577         return (BaseAddRef());
8578     }
8579     ULONG STDMETHODCALLTYPE Release()
8580     {
8581         return (BaseRelease());
8582     }
8583
8584     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
8585     
8586     //-----------------------------------------------------------
8587     // ICorDebugVariableHome
8588     //-----------------------------------------------------------
8589     
8590     COM_METHOD GetCode(ICorDebugCode **ppCode);
8591     
8592     COM_METHOD GetSlotIndex(ULONG32 *pSlotIndex);
8593
8594     COM_METHOD GetArgumentIndex(ULONG32* pArgumentIndex);
8595
8596     COM_METHOD GetLiveRange(ULONG32* pStartOffset,
8597                             ULONG32 *pEndOffset);
8598     
8599     COM_METHOD GetLocationType(VariableLocationType *pLocationType);
8600
8601     COM_METHOD GetRegister(CorDebugRegister *pRegister);
8602     
8603     COM_METHOD GetOffset(LONG *pOffset);
8604 private:
8605     RSSmartPtr<CordbNativeCode> m_pCode;
8606     ICorDebugInfo::NativeVarInfo m_nativeVarInfo;
8607     BOOL m_isLocal;
8608     ULONG m_index;
8609 };
8610
8611
8612 // for an inheritance graph of the ICDValue types, // See file:./ICorDebugValueTypes.vsd for a diagram of the types.  
8613 /* ------------------------------------------------------------------------- *
8614  * Value class
8615  * ------------------------------------------------------------------------- */
8616
8617 class CordbValue : public CordbBase
8618 {
8619 public:
8620     //-----------------------------------------------------------
8621     // Constructor/destructor
8622     //-----------------------------------------------------------
8623     CordbValue(CordbAppDomain * appdomain,
8624                CordbType *      type,
8625                CORDB_ADDRESS    id,
8626                bool             isLiteral,
8627                NeuterList *     pList = NULL);
8628
8629     virtual ~CordbValue();
8630     virtual void Neuter();
8631
8632     //-----------------------------------------------------------
8633     // IUnknown
8634     //-----------------------------------------------------------
8635
8636     ULONG STDMETHODCALLTYPE AddRef()
8637     {
8638         return (BaseAddRef());
8639     }
8640     ULONG STDMETHODCALLTYPE Release()
8641     {
8642         return (BaseRelease());
8643     }
8644
8645     //-----------------------------------------------------------
8646     // ICorDebugValue
8647     //-----------------------------------------------------------
8648
8649     COM_METHOD GetType(CorElementType *pType)
8650     {
8651         LIMITED_METHOD_CONTRACT;
8652
8653         FAIL_IF_NEUTERED(this);
8654         VALIDATE_POINTER_TO_OBJECT(pType, CorElementType *);
8655
8656         *pType = m_type->m_elementType;
8657         return (S_OK);
8658     }
8659
8660     COM_METHOD GetSize(ULONG32 *pSize)
8661     {
8662         LIMITED_METHOD_CONTRACT;
8663
8664         FAIL_IF_NEUTERED(this);
8665         VALIDATE_POINTER_TO_OBJECT(pSize, ULONG32 *);
8666
8667         if (m_size > ULONG_MAX)
8668         {
8669             *pSize = ULONG_MAX;
8670             return (COR_E_OVERFLOW);
8671         }
8672
8673         *pSize = (ULONG)m_size;
8674         return (S_OK);
8675     }
8676
8677     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint);
8678
8679     //-----------------------------------------------------------
8680     // ICorDebugValue2
8681     //-----------------------------------------------------------
8682
8683     COM_METHOD GetExactType(ICorDebugType **ppType);
8684
8685     //-----------------------------------------------------------
8686     // ICorDebugValue3
8687     //-----------------------------------------------------------
8688
8689     COM_METHOD GetSize64(ULONG64 *pSize)
8690     {
8691         LIMITED_METHOD_CONTRACT;
8692
8693         FAIL_IF_NEUTERED(this);
8694         VALIDATE_POINTER_TO_OBJECT(pSize, ULONG64 *);
8695
8696         *pSize = m_size;
8697         return (S_OK);
8698     }
8699
8700     //-----------------------------------------------------------
8701     // Methods not exported through COM
8702     //-----------------------------------------------------------
8703
8704     // Helper for code:CordbValue::CreateValueByType. Create a new instance of CordbGenericValue
8705     static 
8706     void CreateGenericValue(CordbAppDomain *               pAppdomain,
8707                             CordbType *                    pType,
8708                             TargetBuffer                   remoteValue,
8709                             MemoryRange                    localValue,
8710                             EnregisteredValueHomeHolder *  ppRemoteRegAddr,
8711                             ICorDebugValue**               ppValue);
8712
8713     // Helper for code:CordbValue::CreateValueByType. Create a new instance of CordbVCObjectValue or 
8714     // CordbReferenceValue
8715     static                  
8716     void CreateVCObjOrRefValue(CordbAppDomain *               pAppdomain,
8717                                CordbType *                    pType,
8718                                bool                           boxed,
8719                                TargetBuffer                   remoteValue,
8720                                MemoryRange                    localValue,
8721                                EnregisteredValueHomeHolder *  ppRemoteRegAddr,
8722                                ICorDebugValue**               ppValue);
8723
8724     // Create the proper ICDValue instance based on the given element type.
8725     static void CreateValueByType(CordbAppDomain *               appdomain,
8726                                   CordbType *                    type,
8727                                   bool                           boxed,
8728                                   TargetBuffer                   remoteValue,
8729                                   MemoryRange                    localValue,
8730                                   EnregisteredValueHomeHolder *  ppRemoteRegAddr,
8731                                   ICorDebugValue**               ppValue);
8732
8733     // Create the proper ICDValue instance based on the given remote heap object
8734     static ICorDebugValue* CreateHeapValue(CordbAppDomain* pAppDomain,
8735                                            VMPTR_Object vmObj);
8736
8737
8738     // Returns a pointer to the ValueHome field of this instance of CordbValue if one exists or NULL
8739     // otherwise. Therefore, this also tells us indirectly whether this instance of CordbValue is also an
8740     // instance of one of its derived types and thus has a ValueHome field.
8741     virtual
8742     ValueHome * GetValueHome() { return NULL; };
8743
8744     static ULONG32 GetSizeForType(CordbType * pType, BoxedValue boxing);
8745
8746     virtual CordbAppDomain *GetAppDomain()
8747     {
8748         return m_appdomain;
8749     }
8750
8751     HRESULT InternalCreateHandle(
8752         CorDebugHandleType handleType,
8753         ICorDebugHandleValue ** ppHandle);
8754
8755     //-----------------------------------------------------------
8756     // Data members
8757     //-----------------------------------------------------------
8758
8759 public:
8760     CordbAppDomain *            m_appdomain;
8761     RSSmartPtr<CordbType>       m_type;
8762
8763     // size of the value  
8764     SIZE_T                      m_size;
8765
8766     // true if the value is a RS fabrication.
8767     bool                        m_isLiteral;     
8768
8769 };
8770
8771 /* ------------------------------------------------------------------------- *
8772  * Value Breakpoint class
8773  * ------------------------------------------------------------------------- */
8774
8775 class CordbValueBreakpoint : public CordbBreakpoint,
8776                              public ICorDebugValueBreakpoint
8777 {
8778 public:
8779     CordbValueBreakpoint(CordbValue *pValue);
8780
8781
8782 #ifdef _DEBUG
8783     virtual const char * DbgGetName() { return "CordbValueBreakpoint"; }
8784 #endif
8785
8786     //-----------------------------------------------------------
8787     // IUnknown
8788     //-----------------------------------------------------------
8789
8790     ULONG STDMETHODCALLTYPE AddRef()
8791     {
8792         return (BaseAddRef());
8793     }
8794     ULONG STDMETHODCALLTYPE Release()
8795     {
8796         return (BaseRelease());
8797     }
8798     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
8799
8800     //-----------------------------------------------------------
8801     // ICorDebugValueBreakpoint
8802     //-----------------------------------------------------------
8803
8804     COM_METHOD GetValue(ICorDebugValue **ppValue);
8805     COM_METHOD Activate(BOOL bActive);
8806     COM_METHOD IsActive(BOOL *pbActive)
8807     {
8808         VALIDATE_POINTER_TO_OBJECT(pbActive, BOOL *);
8809
8810         return BaseIsActive(pbActive);
8811     }
8812
8813     //-----------------------------------------------------------
8814     // Non-COM methods
8815     //-----------------------------------------------------------
8816
8817     void Disconnect();
8818
8819 public:
8820     CordbValue       *m_value;
8821 };
8822
8823 /* ------------------------------------------------------------------------- *
8824  * Generic Value class
8825  * ------------------------------------------------------------------------- */
8826
8827 class CordbGenericValue : public CordbValue, public ICorDebugGenericValue, public ICorDebugValue2, public ICorDebugValue3
8828 {
8829 public:
8830     CordbGenericValue(CordbAppDomain *              appdomain,
8831                       CordbType *                   type,
8832                       TargetBuffer                  remoteValue,
8833                       EnregisteredValueHomeHolder * ppRemoteRegAddr);
8834
8835     CordbGenericValue(CordbType * pType);
8836     // destructor
8837     ~CordbGenericValue();
8838
8839 #ifdef _DEBUG
8840     virtual const char * DbgGetName() { return "CordbGenericValue"; }
8841 #endif
8842
8843
8844     //-----------------------------------------------------------
8845     // IUnknown
8846     //-----------------------------------------------------------
8847
8848     ULONG STDMETHODCALLTYPE AddRef()
8849     {
8850         return (BaseAddRef());
8851     }
8852     ULONG STDMETHODCALLTYPE Release()
8853     {
8854         return (BaseRelease());
8855     }
8856     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
8857
8858     //-----------------------------------------------------------
8859     // ICorDebugValue
8860     //-----------------------------------------------------------
8861
8862     // gets the type of the value
8863     // Arguments: 
8864     //     output: pType - the type of the value. The caller must guarantee that pType is non-null.
8865     // Return Value: S_OK on success, E_INVALIDARG on failure
8866     COM_METHOD GetType(CorElementType *pType)
8867     {
8868         return (CordbValue::GetType(pType));
8869     }
8870
8871     // gets the size of the value
8872     // Arguments: 
8873     //     output: pSize - the size of the value. The caller must guarantee that pSize is non-null.
8874     // Return Value: S_OK on success, E_INVALIDARG on failure
8875     COM_METHOD GetSize(ULONG32 *pSize)
8876     {
8877         return (CordbValue::GetSize(pSize));
8878     }
8879     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
8880     {
8881         return (CordbValue::CreateBreakpoint(ppBreakpoint));
8882     }
8883
8884     // gets the remote (LS) address of the value. This may return NULL if the 
8885     // value is a literal or resides in a register. 
8886     // Arguments:
8887     //     output: pAddress - the address of the value. The caller must guarantee is
8888     //             non-Null
8889     // Return Value: S_OK on success or E_INVALIDARG if pAddress is null
8890     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress)
8891     {
8892         LIMITED_METHOD_CONTRACT;
8893
8894         FAIL_IF_NEUTERED(this);
8895         VALIDATE_POINTER_TO_OBJECT_OR_NULL(pAddress, CORDB_ADDRESS *);
8896
8897         *pAddress = m_pValueHome ? m_pValueHome->GetAddress() : NULL;
8898         return (S_OK);
8899     }
8900
8901     //-----------------------------------------------------------
8902     // ICorDebugValue2
8903     //-----------------------------------------------------------
8904
8905     COM_METHOD GetExactType(ICorDebugType **ppType)
8906     {
8907         return (CordbValue::GetExactType(ppType));
8908     }
8909
8910     //-----------------------------------------------------------
8911     // ICorDebugValue3
8912     //-----------------------------------------------------------
8913
8914     COM_METHOD GetSize64(ULONG64 *pSize)
8915     {
8916         return (CordbValue::GetSize64(pSize));
8917     }
8918
8919     //-----------------------------------------------------------
8920     // ICorDebugGenericValue
8921     //-----------------------------------------------------------
8922
8923     COM_METHOD GetValue(void *pTo);
8924     COM_METHOD SetValue(void *pFrom);
8925
8926     //-----------------------------------------------------------
8927     // Non-COM methods
8928     //-----------------------------------------------------------
8929
8930     // initialize a generic value by copying the necessary data, either
8931     // from the remote process or from another value in this process.
8932     void Init(MemoryRange localValue);
8933     bool CopyLiteralData(BYTE *pBuffer);
8934
8935     // Returns a pointer to the ValueHome field
8936     virtual
8937     ValueHome * GetValueHome() { return m_pValueHome; };
8938
8939     //-----------------------------------------------------------
8940     // Data members
8941     //-----------------------------------------------------------
8942
8943 private:
8944     // hold copies of up to 64-bit values.
8945     BYTE  m_pCopyOfData[8]; 
8946
8947     // location information--remote or register address
8948     ValueHome * m_pValueHome;
8949 };
8950
8951
8952 /* ------------------------------------------------------------------------- *
8953  * Reference Value class
8954  * ------------------------------------------------------------------------- */
8955
8956 class CordbReferenceValue : public CordbValue, public ICorDebugReferenceValue, public ICorDebugValue2, public ICorDebugValue3
8957 {
8958 public:
8959     CordbReferenceValue(CordbAppDomain *              pAppdomain,
8960                         CordbType *                   pType,
8961                         MemoryRange                   localValue,
8962                         TargetBuffer                  remoteValue,
8963                         EnregisteredValueHomeHolder * ppRegAddr,
8964                         VMPTR_OBJECTHANDLE            vmObjectHandle);
8965     CordbReferenceValue(CordbType * pType);
8966     virtual ~CordbReferenceValue();
8967     virtual void Neuter();
8968
8969
8970 #ifdef _DEBUG
8971     virtual const char * DbgGetName() { return "CordbReferenceValue"; }
8972 #endif
8973
8974     //-----------------------------------------------------------
8975     // IUnknown
8976     //-----------------------------------------------------------
8977
8978     ULONG STDMETHODCALLTYPE AddRef()
8979     {
8980         return (BaseAddRef());
8981     }
8982     ULONG STDMETHODCALLTYPE Release()
8983     {
8984         return (BaseRelease());
8985     }
8986     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
8987
8988     //-----------------------------------------------------------
8989     // ICorDebugValue
8990     //-----------------------------------------------------------
8991
8992     COM_METHOD GetType(CorElementType *pType);
8993
8994     // get the size of the reference
8995     // Arguments: 
8996     //     output: pSize - the size of the value--this must be non-NULL
8997     // Return Value: S_OK on success or E_INVALIDARG
8998     COM_METHOD GetSize(ULONG32 *pSize)
8999     {
9000         return (CordbValue::GetSize(pSize));
9001     }
9002
9003     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress);
9004     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
9005     {
9006         return (CordbValue::CreateBreakpoint(ppBreakpoint));
9007     }
9008
9009     //-----------------------------------------------------------
9010     // ICorDebugValue2
9011     //-----------------------------------------------------------
9012
9013     COM_METHOD GetExactType(ICorDebugType **ppType)
9014     {
9015         return (CordbValue::GetExactType(ppType));
9016     }
9017
9018     //-----------------------------------------------------------
9019     // ICorDebugValue3
9020     //-----------------------------------------------------------
9021
9022     COM_METHOD GetSize64(ULONG64 *pSize)
9023     {
9024         return (CordbValue::GetSize64(pSize));
9025     }
9026
9027     //-----------------------------------------------------------
9028     // ICorDebugReferenceValue
9029     //-----------------------------------------------------------
9030
9031     COM_METHOD IsNull(BOOL * pfIsNull);
9032     COM_METHOD GetValue(CORDB_ADDRESS *pAddress);
9033     COM_METHOD SetValue(CORDB_ADDRESS address);
9034     COM_METHOD Dereference(ICorDebugValue **ppValue);
9035     COM_METHOD DereferenceStrong(ICorDebugValue **ppValue);
9036
9037     //-----------------------------------------------------------
9038     // Non-COM methods
9039     //-----------------------------------------------------------
9040
9041     // Helper function for SanityCheckPointer. Make an attempt to read memory at the address which is the
9042     // value of the reference.
9043     void TryDereferencingTarget();
9044
9045     // Do a sanity check on the pointer which is the value of the object reference. We can't efficiently
9046     // ensure that the pointer is really good, so we settle for a quick check just to make sure the memory at
9047     // the address is readable. We're actually just checking that we can dereference the pointer.
9048     // If the address is invalid, this will throw.
9049     void SanityCheckPointer (CorElementType type);
9050
9051     // get information about the reference when it's not an object address but another kind of pointer type:
9052     // ELEMENT_TYPE_BYREF, ELEMENT_TYPE_PTR or ELEMENT_TYPE_FNPTR
9053     void GetPointerData(CorElementType type, MemoryRange localValue);
9054
9055     // get basic object specific data when a reference points to an object, plus extra data if the object is
9056     // an array or string
9057     static
9058     void GetObjectData(CordbProcess *            pProcess, 
9059                        void *                    objectAddress, 
9060                        CorElementType            type, 
9061                        VMPTR_AppDomain           vmAppdomain,
9062                        DebuggerIPCE_ObjectData * pInfo);
9063
9064     // get information about a TypedByRef object when the reference is the address of a TypedByRef structure.
9065     static
9066     void GetTypedByRefData(CordbProcess *            pProcess, 
9067                            CORDB_ADDRESS             pTypedByRef, 
9068                            CorElementType            type, 
9069                            VMPTR_AppDomain           vmAppDomain,
9070                            DebuggerIPCE_ObjectData * pInfo);
9071
9072     //  get the address of the object referenced
9073     void * GetObjectAddress(MemoryRange localValue);
9074
9075     // update type information after initializing -- when we initialize, we may get more exact type
9076     // information than we previously had
9077     void UpdateTypeInfo();
9078
9079     // Initialize this CordbReferenceValue. This may involve inspecting the LS to get information about the
9080     // referent.
9081     HRESULT InitRef(MemoryRange localValue);
9082
9083     bool CopyLiteralData(BYTE *pBuffer);
9084
9085     static HRESULT Build(CordbAppDomain *              appdomain,
9086                          CordbType *                   type,
9087                          TargetBuffer                  remoteValue,
9088                          MemoryRange                   localValue,
9089                          VMPTR_OBJECTHANDLE            vmObjectHandle,
9090                          EnregisteredValueHomeHolder * ppRemoteRegAddr,
9091                          CordbReferenceValue**         ppValue);
9092
9093     static HRESULT BuildFromGCHandle(CordbAppDomain *pAppDomain, VMPTR_OBJECTHANDLE gcHandle, ICorDebugReferenceValue ** pOutRef);
9094
9095     // Common dereference routine shared by both CordbReferenceValue + CordbHandleValue
9096     static HRESULT DereferenceCommon(CordbAppDomain *          pAppDomain,
9097                                      CordbType *               pType,
9098                                      CordbType *               pRealTypeOfTypedByref,
9099                                      DebuggerIPCE_ObjectData * m_pInfo,
9100                                      ICorDebugValue **         ppValue);
9101
9102     // Returns a pointer to the ValueHome field
9103     virtual
9104     ValueHome * GetValueHome() { return m_valueHome.m_pHome; };
9105
9106     //-----------------------------------------------------------
9107     // Data members
9108     //-----------------------------------------------------------
9109
9110 public:
9111     DebuggerIPCE_ObjectData  m_info;
9112     CordbType *              m_realTypeOfTypedByref; // weak ref
9113
9114     RefValueHome             m_valueHome;
9115
9116     // Indicates when we last syncronized our stored data (m_info) from the left side
9117     UINT                     m_continueCounterLastSync;
9118 };
9119
9120 /* ------------------------------------------------------------------------- *
9121  * Object Value class
9122  *
9123  * Because of the oddness of string objects in the Runtime we have one
9124  * object that implements both ObjectValue and StringValue. There is a
9125  * definite string type, but its really just an object of the string
9126  * class. Furthermore, you can have a variable whose type is listed as
9127  * "class", but its an instance of the string class and therefore needs
9128  * to be treated like a string. 
9129  * ------------------------------------------------------------------------- */
9130
9131 class CordbObjectValue : public CordbValue, 
9132                          public ICorDebugObjectValue,
9133                          public ICorDebugObjectValue2,
9134                          public ICorDebugGenericValue,
9135                          public ICorDebugStringValue, 
9136                          public ICorDebugValue2,
9137                          public ICorDebugValue3,
9138                          public ICorDebugHeapValue2,
9139                          public ICorDebugHeapValue3,
9140                          public ICorDebugExceptionObjectValue,
9141                          public ICorDebugComObjectValue
9142 {
9143 public:
9144     
9145     CordbObjectValue(CordbAppDomain *          appdomain,
9146                      CordbType *               type,
9147                      TargetBuffer              remoteValue,
9148                      DebuggerIPCE_ObjectData * pObjectData );
9149                      
9150     virtual ~CordbObjectValue();
9151
9152
9153     virtual void Neuter();
9154 #ifdef _DEBUG
9155     virtual const char * DbgGetName() { return "CordbObjectValue"; }
9156 #endif
9157
9158     //-----------------------------------------------------------
9159     // IUnknown
9160     //-----------------------------------------------------------
9161
9162     ULONG STDMETHODCALLTYPE AddRef()
9163     {
9164         return (BaseAddRef());
9165     }
9166     ULONG STDMETHODCALLTYPE Release()
9167     {
9168         return (BaseRelease());
9169     }
9170     COM_METHOD QueryInterface(REFIID riid, void ** ppInterface);
9171
9172     //-----------------------------------------------------------
9173     // ICorDebugValue
9174     //-----------------------------------------------------------
9175
9176     COM_METHOD GetType(CorElementType * pType);
9177     COM_METHOD GetSize(ULONG32 * pSize);
9178     COM_METHOD GetAddress(CORDB_ADDRESS * pAddress);
9179     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint ** ppBreakpoint);
9180
9181     //-----------------------------------------------------------
9182     // ICorDebugValue2
9183     //-----------------------------------------------------------
9184
9185     COM_METHOD GetExactType(ICorDebugType ** ppType)
9186     {
9187         return (CordbValue::GetExactType(ppType));
9188     }
9189
9190     //-----------------------------------------------------------
9191     // ICorDebugValue3
9192     //-----------------------------------------------------------
9193
9194     COM_METHOD GetSize64(ULONG64 *pSize);
9195
9196     //-----------------------------------------------------------
9197     // ICorDebugHeapValue
9198     //-----------------------------------------------------------
9199
9200     COM_METHOD IsValid(BOOL * pfIsValid);
9201     COM_METHOD CreateRelocBreakpoint(ICorDebugValueBreakpoint ** ppBreakpoint);
9202
9203     //-----------------------------------------------------------
9204     // ICorDebugHeapValue2
9205     //-----------------------------------------------------------
9206     COM_METHOD CreateHandle(CorDebugHandleType type, ICorDebugHandleValue ** ppHandle);
9207
9208     //-----------------------------------------------------------
9209     // ICorDebugHeapValue3
9210     //-----------------------------------------------------------
9211     COM_METHOD GetThreadOwningMonitorLock(ICorDebugThread **ppThread, DWORD *pAcquisitionCount);
9212     COM_METHOD GetMonitorEventWaitList(ICorDebugThreadEnum **ppThreadEnum);
9213
9214     //-----------------------------------------------------------
9215     // ICorDebugObjectValue
9216     //-----------------------------------------------------------
9217
9218     COM_METHOD GetClass(ICorDebugClass ** ppClass);
9219     COM_METHOD GetFieldValue(ICorDebugClass *  pClass,
9220                              mdFieldDef        fieldDef,
9221                              ICorDebugValue ** ppValue);
9222     COM_METHOD GetVirtualMethod(mdMemberRef memberRef,
9223                                 ICorDebugFunction **ppFunction);
9224     COM_METHOD GetContext(ICorDebugContext ** ppContext);
9225     COM_METHOD IsValueClass(BOOL * pfIsValueClass);
9226     COM_METHOD GetManagedCopy(IUnknown ** ppObject);
9227     COM_METHOD SetFromManagedCopy(IUnknown * pObject);
9228
9229     COM_METHOD GetFieldValueForType(ICorDebugType *   pType,
9230                                     mdFieldDef        fieldDef,
9231                                     ICorDebugValue ** ppValue);
9232
9233     COM_METHOD GetVirtualMethodAndType(mdMemberRef          memberRef,
9234                                        ICorDebugFunction ** ppFunction,
9235                                        ICorDebugType **     ppType);
9236
9237     //-----------------------------------------------------------
9238     // ICorDebugGenericValue
9239     //-----------------------------------------------------------
9240
9241     COM_METHOD GetValue(void * pTo);
9242     COM_METHOD SetValue(void * pFrom);
9243
9244     //-----------------------------------------------------------
9245     // ICorDebugStringValue
9246     //-----------------------------------------------------------
9247     COM_METHOD GetLength(ULONG32 * pcchString);
9248     COM_METHOD GetString(ULONG32   cchString,
9249                          ULONG32 * ppcchStrin,
9250                          __out_ecount_opt(cchString) WCHAR     szString[]);
9251
9252     //-----------------------------------------------------------
9253     // ICorDebugExceptionObjectValue
9254     //-----------------------------------------------------------
9255     COM_METHOD EnumerateExceptionCallStack(ICorDebugExceptionObjectCallStackEnum** ppCallStackEnum);
9256
9257     //-----------------------------------------------------------
9258     // ICorDebugComObjectValue
9259     //-----------------------------------------------------------
9260     COM_METHOD GetCachedInterfaceTypes(BOOL bIInspectableOnly, 
9261                         ICorDebugTypeEnum** ppInterfacesEnum);
9262
9263     COM_METHOD GetCachedInterfacePointers(BOOL bIInspectableOnly, 
9264                         ULONG32 celt,
9265                         ULONG32 *pcEltFetched,
9266                         CORDB_ADDRESS * ptrs);
9267
9268     //-----------------------------------------------------------
9269     // Non-COM methods
9270     //-----------------------------------------------------------
9271
9272     HRESULT Init();
9273
9274     DebuggerIPCE_ObjectData GetInfo() { return m_info; }
9275     CordbHangingFieldTable * GetHangingFieldTable() { return &m_hangingFieldsInstance; }
9276
9277     // Returns a pointer to the ValueHome field
9278     virtual
9279     RemoteValueHome * GetValueHome() { return &m_valueHome; };
9280
9281 protected:
9282     //-----------------------------------------------------------
9283     // Data members
9284     //-----------------------------------------------------------
9285     DebuggerIPCE_ObjectData  m_info;
9286     BYTE *                   m_pObjectCopy;     // local cached copy of the object
9287     BYTE *                   m_objectLocalVars; // var base in _this_ process
9288                                                 // points _into_ m_pObjectCopy
9289     BYTE *                   m_stringBuffer;    // points _into_ m_pObjectCopy
9290
9291     // remote location information
9292     RemoteValueHome          m_valueHome;
9293
9294     // If instances fields are added by EnC, their storage will be off the objects
9295     // syncblock.  Cache per-object information about such fields here.
9296     CordbHangingFieldTable   m_hangingFieldsInstance;
9297
9298 private:
9299     HRESULT IsExceptionObject();
9300
9301     BOOL                     m_fIsExceptionObject;
9302
9303     HRESULT IsRcw();
9304
9305     BOOL                     m_fIsRcw;
9306 };
9307
9308 /* ------------------------------------------------------------------------- *
9309  * Value Class Object Value class
9310  * ------------------------------------------------------------------------- */
9311
9312 class CordbVCObjectValue : public CordbValue,
9313                            public ICorDebugObjectValue, public ICorDebugObjectValue2,
9314                            public ICorDebugGenericValue, public ICorDebugValue2,
9315                            public ICorDebugValue3
9316 {
9317 public:
9318     CordbVCObjectValue(CordbAppDomain *               pAppdomain,
9319                        CordbType *                    pType,
9320                        TargetBuffer                   remoteValue,
9321                        EnregisteredValueHomeHolder *  ppRemoteRegAddr);
9322     virtual ~CordbVCObjectValue();
9323
9324 #ifdef _DEBUG
9325     virtual const char * DbgGetName() { return "CordbVCObjectValue"; }
9326 #endif
9327
9328     //-----------------------------------------------------------
9329     // IUnknown
9330     //-----------------------------------------------------------
9331
9332     ULONG STDMETHODCALLTYPE AddRef()
9333     {
9334         return (BaseAddRef());
9335     }
9336     ULONG STDMETHODCALLTYPE Release()
9337     {
9338         return (BaseRelease());
9339     }
9340     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9341
9342     //-----------------------------------------------------------
9343     // ICorDebugValue
9344     //-----------------------------------------------------------
9345
9346     COM_METHOD GetType(CorElementType *pType);
9347
9348     COM_METHOD GetSize(ULONG32 *pSize)
9349     {
9350         return (CordbValue::GetSize(pSize));
9351     }
9352     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
9353     {
9354         return (CordbValue::CreateBreakpoint(ppBreakpoint));
9355     }
9356
9357     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress)
9358     {
9359         LIMITED_METHOD_CONTRACT;
9360
9361         FAIL_IF_NEUTERED(this);
9362         VALIDATE_POINTER_TO_OBJECT(pAddress, CORDB_ADDRESS *);
9363
9364         *pAddress = m_pValueHome->GetAddress();
9365         return (S_OK);
9366     }
9367
9368     //-----------------------------------------------------------
9369     // ICorDebugValue2
9370     //-----------------------------------------------------------
9371
9372     COM_METHOD GetExactType(ICorDebugType **ppType)
9373     {
9374         return (CordbValue::GetExactType(ppType));
9375     }
9376
9377     //-----------------------------------------------------------
9378     // ICorDebugValue3
9379     //-----------------------------------------------------------
9380
9381     COM_METHOD GetSize64(ULONG64 *pSize)
9382     {
9383         return (CordbValue::GetSize64(pSize));
9384     }
9385
9386     //-----------------------------------------------------------
9387     // ICorDebugObjectValue
9388     //-----------------------------------------------------------
9389
9390     COM_METHOD GetClass(ICorDebugClass **ppClass);
9391     COM_METHOD GetFieldValue(ICorDebugClass *pClass,
9392                              mdFieldDef fieldDef,
9393                              ICorDebugValue **ppValue);
9394     COM_METHOD GetVirtualMethod(mdMemberRef memberRef,
9395                                 ICorDebugFunction **ppFunction);
9396     COM_METHOD GetContext(ICorDebugContext **ppContext);
9397     COM_METHOD IsValueClass(BOOL *pbIsValueClass);
9398     COM_METHOD GetManagedCopy(IUnknown **ppObject);
9399     COM_METHOD SetFromManagedCopy(IUnknown *pObject);
9400     COM_METHOD GetFieldValueForType(ICorDebugType * pType,
9401                                     mdFieldDef fieldDef,
9402                                     ICorDebugValue ** ppValue);
9403     COM_METHOD GetVirtualMethodAndType(mdMemberRef memberRef,
9404                                        ICorDebugFunction **ppFunction,
9405                                        ICorDebugType **ppType);
9406
9407     //-----------------------------------------------------------
9408     // ICorDebugGenericValue
9409     //-----------------------------------------------------------
9410
9411     COM_METHOD GetValue(void *pTo);
9412     COM_METHOD SetValue(void *pFrom);
9413
9414     //-----------------------------------------------------------
9415     // Non-COM methods
9416     //-----------------------------------------------------------
9417
9418     // Initializes the Right-Side's representation of a Value Class object.
9419     HRESULT Init(MemoryRange localValue);
9420     //HRESULT ResolveValueClass();
9421     CordbClass *GetClass();
9422
9423     // Returns a pointer to the ValueHome field
9424     virtual
9425     ValueHome * GetValueHome() { return m_pValueHome; };
9426
9427     //-----------------------------------------------------------
9428     // Data members
9429     //-----------------------------------------------------------
9430
9431 private:
9432
9433     // local cached copy of the value class
9434     BYTE *   m_pObjectCopy;
9435
9436     // location information
9437     ValueHome * m_pValueHome;
9438 };
9439
9440
9441 /* ------------------------------------------------------------------------- *
9442  * Box Value class
9443  * ------------------------------------------------------------------------- */
9444
9445 class CordbBoxValue : public CordbValue, 
9446                       public ICorDebugBoxValue,
9447                       public ICorDebugGenericValue,
9448                       public ICorDebugValue2,
9449                       public ICorDebugValue3,
9450                       public ICorDebugHeapValue2,
9451                       public ICorDebugHeapValue3
9452 {
9453 public:
9454     CordbBoxValue(CordbAppDomain *  appdomain,
9455                   CordbType *       type,
9456                   TargetBuffer      remoteValue,
9457                   ULONG32           size,
9458                   SIZE_T            offsetToVars);
9459     virtual ~CordbBoxValue();
9460
9461 #ifdef _DEBUG
9462     virtual const char * DbgGetName() { return "CordbBoxValue"; }
9463 #endif
9464
9465     //-----------------------------------------------------------
9466     // IUnknown
9467     //-----------------------------------------------------------
9468
9469     ULONG STDMETHODCALLTYPE AddRef()
9470     {
9471         return (BaseAddRef());
9472     }
9473     ULONG STDMETHODCALLTYPE Release()
9474     {
9475         return (BaseRelease());
9476     }
9477     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9478
9479     //-----------------------------------------------------------
9480     // ICorDebugValue
9481     //-----------------------------------------------------------
9482
9483     COM_METHOD GetType(CorElementType *pType);
9484
9485     COM_METHOD GetSize(ULONG32 *pSize)
9486     {
9487         return (CordbValue::GetSize(pSize));
9488     }
9489     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
9490     {
9491         return (CordbValue::CreateBreakpoint(ppBreakpoint));
9492     }
9493
9494      COM_METHOD GetAddress(CORDB_ADDRESS *pAddress)
9495     {
9496         LIMITED_METHOD_CONTRACT;
9497
9498         FAIL_IF_NEUTERED(this);
9499         VALIDATE_POINTER_TO_OBJECT(pAddress, CORDB_ADDRESS *);
9500
9501         *pAddress = m_valueHome.GetAddress();
9502         return (S_OK);
9503     }
9504
9505     //-----------------------------------------------------------
9506     // ICorDebugValue2
9507     //-----------------------------------------------------------
9508
9509     COM_METHOD GetExactType(ICorDebugType **ppType)
9510     {
9511         return (CordbValue::GetExactType(ppType));
9512     }
9513
9514     //-----------------------------------------------------------
9515     // ICorDebugValue3
9516     //-----------------------------------------------------------
9517
9518     COM_METHOD GetSize64(ULONG64 *pSize)
9519     {
9520         return (CordbValue::GetSize64(pSize));
9521     }
9522
9523     //-----------------------------------------------------------
9524     // ICorDebugHeapValue
9525     //-----------------------------------------------------------
9526
9527     COM_METHOD IsValid(BOOL *pbValid);
9528     COM_METHOD CreateRelocBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint);
9529
9530     //-----------------------------------------------------------
9531     // ICorDebugHeapValue2
9532     //-----------------------------------------------------------
9533     COM_METHOD CreateHandle(CorDebugHandleType type, ICorDebugHandleValue ** ppHandle);
9534
9535     //-----------------------------------------------------------
9536     // ICorDebugHeapValue3
9537     //-----------------------------------------------------------
9538     COM_METHOD GetThreadOwningMonitorLock(ICorDebugThread **ppThread, DWORD *pAcquisitionCount);
9539     COM_METHOD GetMonitorEventWaitList(ICorDebugThreadEnum **ppThreadEnum);
9540
9541     //-----------------------------------------------------------
9542     // ICorDebugGenericValue
9543     //-----------------------------------------------------------
9544
9545     COM_METHOD GetValue(void *pTo);
9546     COM_METHOD SetValue(void *pFrom);
9547
9548     //-----------------------------------------------------------
9549     // ICorDebugBoxValue
9550     //-----------------------------------------------------------
9551     COM_METHOD GetObject(ICorDebugObjectValue **ppObject);
9552
9553     // Returns a pointer to the ValueHome field
9554     virtual
9555     RemoteValueHome * GetValueHome() { return &m_valueHome; };
9556
9557     //-----------------------------------------------------------
9558     // Data members
9559     //-----------------------------------------------------------
9560
9561 private:
9562     SIZE_T          m_offsetToVars;
9563
9564     // remote location information
9565     RemoteValueHome m_valueHome;
9566
9567 };
9568
9569 /* ------------------------------------------------------------------------- *
9570  * Array Value class
9571  * ------------------------------------------------------------------------- */
9572
9573 class CordbArrayValue : public CordbValue, 
9574                         public ICorDebugArrayValue,
9575                         public ICorDebugGenericValue,
9576                         public ICorDebugValue2,
9577                         public ICorDebugValue3,
9578                         public ICorDebugHeapValue2,
9579                         public ICorDebugHeapValue3
9580 {
9581 public:
9582     CordbArrayValue(CordbAppDomain *          appdomain,
9583                     CordbType *               type,
9584                     DebuggerIPCE_ObjectData * pObjectInfo,
9585                     TargetBuffer              remoteValue);
9586     virtual ~CordbArrayValue();
9587
9588 #ifdef _DEBUG
9589     virtual const char * DbgGetName() { return "CordbArrayValue"; }
9590 #endif
9591
9592     //-----------------------------------------------------------
9593     // IUnknown
9594     //-----------------------------------------------------------
9595
9596     ULONG STDMETHODCALLTYPE AddRef()
9597     {
9598         return (BaseAddRef());
9599     }
9600     ULONG STDMETHODCALLTYPE Release()
9601     {
9602         return (BaseRelease());
9603     }
9604     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9605
9606     //-----------------------------------------------------------
9607     // ICorDebugValue
9608     //-----------------------------------------------------------
9609
9610     COM_METHOD GetType(CorElementType *pType)
9611     {
9612         return (CordbValue::GetType(pType));
9613     }
9614     COM_METHOD GetSize(ULONG32 *pSize)
9615     {
9616         return (CordbValue::GetSize(pSize));
9617     }
9618     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress)
9619     {
9620         VALIDATE_POINTER_TO_OBJECT(pAddress, CORDB_ADDRESS *);
9621         *pAddress = m_valueHome.GetAddress();
9622         return (S_OK);
9623     }
9624     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
9625     {
9626         return (CordbValue::CreateBreakpoint(ppBreakpoint));
9627     }
9628
9629     //-----------------------------------------------------------
9630     // ICorDebugValue2
9631     //-----------------------------------------------------------
9632
9633     COM_METHOD GetExactType(ICorDebugType **ppType)
9634     {
9635         return (CordbValue::GetExactType(ppType));
9636     }
9637
9638     //-----------------------------------------------------------
9639     // ICorDebugValue3
9640     //-----------------------------------------------------------
9641
9642     COM_METHOD GetSize64(ULONG64 *pSize)
9643     {
9644         return (CordbValue::GetSize64(pSize));
9645     }
9646
9647     //-----------------------------------------------------------
9648     // ICorDebugHeapValue
9649     //-----------------------------------------------------------
9650
9651     COM_METHOD IsValid(BOOL *pbValid);
9652     COM_METHOD CreateRelocBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint);
9653
9654     //-----------------------------------------------------------
9655     // ICorDebugHeapValue2
9656     //-----------------------------------------------------------
9657     COM_METHOD CreateHandle(CorDebugHandleType type, ICorDebugHandleValue ** ppHandle);
9658
9659     //-----------------------------------------------------------
9660     // ICorDebugHeapValue3
9661     //-----------------------------------------------------------
9662     COM_METHOD GetThreadOwningMonitorLock(ICorDebugThread **ppThread, DWORD *pAcquisitionCount);
9663     COM_METHOD GetMonitorEventWaitList(ICorDebugThreadEnum **ppThreadEnum);
9664
9665     //-----------------------------------------------------------
9666     // ICorDebugArrayValue
9667     //-----------------------------------------------------------
9668
9669     COM_METHOD GetElementType(CorElementType * pType);
9670     COM_METHOD GetRank(ULONG32 * pnRank);
9671     COM_METHOD GetCount(ULONG32 * pnCount);
9672     COM_METHOD GetDimensions(ULONG32 cdim, ULONG32 dims[]);
9673     COM_METHOD HasBaseIndicies(BOOL * pbHasBaseIndices);
9674     COM_METHOD GetBaseIndicies(ULONG32 cdim, ULONG32 indices[]);
9675     COM_METHOD GetElement(ULONG32 cdim, ULONG32 indices[], ICorDebugValue ** ppValue);
9676     COM_METHOD GetElementAtPosition(ULONG32 nIndex, ICorDebugValue ** ppValue);
9677
9678     //-----------------------------------------------------------
9679     // ICorDebugGenericValue
9680     //-----------------------------------------------------------
9681
9682     COM_METHOD GetValue(void *pTo);
9683     COM_METHOD SetValue(void *pFrom);
9684
9685     //-----------------------------------------------------------
9686     // Non-COM methods
9687     //-----------------------------------------------------------
9688
9689     HRESULT Init();
9690
9691     // Returns a pointer to the ValueHome field
9692     virtual
9693     RemoteValueHome * GetValueHome() { return &m_valueHome; };
9694
9695     //-----------------------------------------------------------
9696     // Data members
9697     //-----------------------------------------------------------
9698
9699 private:
9700     // contains information about the array, such as rank, number of elements, element size, etc.
9701     DebuggerIPCE_ObjectData  m_info;
9702
9703     // type of the elements
9704     CordbType               *m_elemtype;
9705
9706     // consists of three parts: a vector containing the lower bounds for each dimension,
9707     //                          a vector containing the upper bounds for each dimension,
9708     //                          a local cached copy of (part of) the array--initialized lazily when we 
9709     //                             request a particular element. If the array is large, we will store only
9710     //                             part of it, swapping out the cached segment as necessary to retrieve 
9711     //                             requested elements.
9712     BYTE *                   m_pObjectCopy;
9713
9714     // points to the beginning of the vector containing the lower bounds for each dimension in m_pObjectCopy
9715     DWORD *                  m_arrayLowerBase; 
9716
9717     // points to the beginning of the vector containing the lower bounds for each dimension in m_pObjectCopy
9718     DWORD *                  m_arrayUpperBase;
9719     // index of lower bound of data currently stored in m_pObjectCopy
9720     SIZE_T                   m_idxLower;
9721
9722     // index of upper bound of data currently stored in m_pObjectCopy
9723     SIZE_T                   m_idxUpper; 
9724
9725     // remote location information
9726     RemoteValueHome m_valueHome;
9727
9728 };
9729
9730 class CordbHandleValue : public CordbValue, public ICorDebugHandleValue, public ICorDebugValue2, public ICorDebugValue3
9731 {
9732 public:
9733     CordbHandleValue(CordbAppDomain *appdomain,
9734                      CordbType *type,
9735                      CorDebugHandleType handleType);
9736     HRESULT Init(VMPTR_OBJECTHANDLE pHandle);
9737
9738     virtual ~CordbHandleValue();
9739
9740     virtual void Neuter();
9741     virtual void NeuterLeftSideResources();
9742
9743 #ifdef _DEBUG
9744     virtual const char * DbgGetName() { return "CordbHandleValue"; }
9745 #endif
9746
9747
9748     //-----------------------------------------------------------
9749     // IUnknown
9750     //-----------------------------------------------------------
9751
9752     ULONG STDMETHODCALLTYPE AddRef()
9753     {
9754         return (BaseAddRef());
9755     }
9756     ULONG STDMETHODCALLTYPE Release()
9757     {
9758         return (BaseRelease());
9759     }
9760     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9761
9762     //-----------------------------------------------------------
9763     // ICorDebugHandleValue interface
9764     //-----------------------------------------------------------
9765     COM_METHOD GetHandleType(CorDebugHandleType *pType);
9766
9767
9768     /*
9769       * The final release of the interface will also dispose of the handle. This
9770       * API provides the ability for client to early dispose the handle.
9771       *
9772       */
9773     COM_METHOD Dispose();
9774
9775     //-----------------------------------------------------------
9776     // ICorDebugValue interface
9777     //-----------------------------------------------------------
9778     COM_METHOD GetType(CorElementType *pType);
9779     COM_METHOD GetSize(ULONG32 *pSize);
9780     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress);
9781     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint);
9782
9783     //-----------------------------------------------------------
9784     // ICorDebugValue2
9785     //-----------------------------------------------------------
9786
9787     COM_METHOD GetExactType(ICorDebugType **ppType)
9788     {
9789         FAIL_IF_NEUTERED(this);
9790         
9791         // If AppDomain is already unloaded, return error
9792         if (m_appdomain->IsNeutered() == TRUE)
9793         {
9794             return COR_E_APPDOMAINUNLOADED;
9795         }
9796         if (m_vmHandle.IsNull())
9797         {
9798             return CORDBG_E_HANDLE_HAS_BEEN_DISPOSED;
9799         }
9800
9801         return (CordbValue::GetExactType(ppType));
9802     }
9803
9804     //-----------------------------------------------------------
9805     // ICorDebugValue3
9806     //-----------------------------------------------------------
9807
9808     COM_METHOD GetSize64(ULONG64 *pSize);
9809
9810     //-----------------------------------------------------------
9811     // ICorDebugReferenceValue interface
9812     //-----------------------------------------------------------
9813
9814     COM_METHOD IsNull(BOOL *pbNull);
9815     COM_METHOD GetValue(CORDB_ADDRESS *pValue);
9816     COM_METHOD SetValue(CORDB_ADDRESS value);
9817     COM_METHOD Dereference(ICorDebugValue **ppValue);
9818     COM_METHOD DereferenceStrong(ICorDebugValue **ppValue);
9819
9820     //-----------------------------------------------------------
9821     // Non-COM methods
9822     //-----------------------------------------------------------
9823
9824     // Returns a pointer to the ValueHome field
9825     virtual
9826     RemoteValueHome * GetValueHome() { return NULL; };
9827
9828 private:
9829     //BOOL RefreshHandleValue(void **pObjectToken);
9830     HRESULT RefreshHandleValue();
9831
9832     // EE object handle pointer. Can be casted to OBJECTHANDLE when go to LS
9833     // This instance owns the handle object and must call into the VM to release
9834     // it.
9835     // If this is non-null, then we increment code:CordbProces::IncrementOutstandingHandles.
9836     // Once it goes null, we should decrement the count.
9837     // Use AssignHandle, ClearHandle to keep this in sync.
9838     VMPTR_OBJECTHANDLE  m_vmHandle;         
9839
9840
9841     void AssignHandle(VMPTR_OBJECTHANDLE handle);
9842     void ClearHandle();
9843
9844     BOOL                m_fCanBeValid;      // true if object "can" be valid. False when object is no longer valid.
9845     CorDebugHandleType m_handleType;        // handle type can be strong or weak
9846     DebuggerIPCE_ObjectData  m_info;
9847 ; // ICORDebugClass of this object when we create the handle
9848 };
9849
9850 // This class actually has the implementation for ICorDebugHeap3 interfaces. Any value which implements
9851 // the interface just delegates to these static calls.
9852 class CordbHeapValue3Impl
9853 {
9854 public:
9855     static HRESULT GetThreadOwningMonitorLock(CordbProcess* pProcess,
9856                                               CORDB_ADDRESS remoteObjAddress,
9857                                               ICorDebugThread **ppThread,
9858                                               DWORD *pAcquistionCount);
9859     static HRESULT GetMonitorEventWaitList(CordbProcess* pProcess,
9860                                            CORDB_ADDRESS remoteObjAddress,
9861                                            ICorDebugThreadEnum **ppThreadEnum);
9862 };
9863
9864 /* ------------------------------------------------------------------------- *
9865  * Eval class
9866  * ------------------------------------------------------------------------- */
9867
9868 class CordbEval : public CordbBase, public ICorDebugEval, public ICorDebugEval2
9869 {
9870 public:
9871     CordbEval(CordbThread* pThread);
9872     virtual ~CordbEval();
9873
9874 #ifdef _DEBUG
9875     virtual const char * DbgGetName() { return "CordbEval"; }
9876 #endif
9877
9878     virtual void Neuter();
9879     virtual void NeuterLeftSideResources();
9880
9881     //-----------------------------------------------------------
9882     // IUnknown
9883     //-----------------------------------------------------------
9884
9885     ULONG STDMETHODCALLTYPE AddRef()
9886     {
9887         return (BaseAddRef());
9888     }
9889     ULONG STDMETHODCALLTYPE Release()
9890     {
9891         return (BaseRelease());
9892     }
9893     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9894
9895     //-----------------------------------------------------------
9896     // ICorDebugEval
9897     //-----------------------------------------------------------
9898
9899     COM_METHOD CallFunction(ICorDebugFunction *pFunction,
9900                             ULONG32 nArgs,
9901                             ICorDebugValue *ppArgs[]);
9902     COM_METHOD NewObject(ICorDebugFunction *pConstructor,
9903                          ULONG32 nArgs,
9904                          ICorDebugValue *ppArgs[]);
9905     COM_METHOD NewObjectNoConstructor(ICorDebugClass *pClass);
9906     COM_METHOD NewString(LPCWSTR string);
9907     COM_METHOD NewArray(CorElementType elementType,
9908                         ICorDebugClass *pElementClass,
9909                         ULONG32 rank,
9910                         ULONG32 dims[],
9911                         ULONG32 lowBounds[]);
9912     COM_METHOD IsActive(BOOL *pbActive);
9913     COM_METHOD Abort();
9914     COM_METHOD GetResult(ICorDebugValue **ppResult);
9915     COM_METHOD GetThread(ICorDebugThread **ppThread);
9916     COM_METHOD CreateValue(CorElementType elementType,
9917                            ICorDebugClass *pElementClass,
9918                            ICorDebugValue **ppValue);
9919     COM_METHOD NewStringWithLength(LPCWSTR wszString, UINT iLength);
9920
9921     COM_METHOD CallParameterizedFunction(ICorDebugFunction * pFunction,
9922                                          ULONG32 nTypeArgs,
9923                                          ICorDebugType * rgpTypeArgs[],
9924                                          ULONG32 nArgs,
9925                                          ICorDebugValue * rgpArgs[]);
9926
9927     COM_METHOD CreateValueForType(ICorDebugType *pType,
9928                                   ICorDebugValue **ppValue);
9929
9930     COM_METHOD NewParameterizedObject(ICorDebugFunction * pConstructor,
9931                                       ULONG32 nTypeArgs,
9932                                       ICorDebugType * rgpTypeArgs[],
9933                                       ULONG32 nArgs,
9934                                       ICorDebugValue * rgpArgs[]);
9935
9936     COM_METHOD NewParameterizedObjectNoConstructor(ICorDebugClass * pClass,
9937                                                    ULONG32 nTypeArgs,
9938                                                    ICorDebugType * rgpTypeArgs[]);
9939
9940     COM_METHOD NewParameterizedArray(ICorDebugType * pElementType,
9941                                      ULONG32 rank,
9942                                      ULONG32 dims[],
9943                                      ULONG32 lowBounds[]);
9944
9945     //-----------------------------------------------------------
9946     // ICorDebugEval2
9947     //-----------------------------------------------------------
9948
9949     COM_METHOD RudeAbort();
9950
9951     //-----------------------------------------------------------
9952     // Non-COM methods
9953     //-----------------------------------------------------------
9954     HRESULT GatherArgInfo(ICorDebugValue *pValue,
9955                           DebuggerIPCE_FuncEvalArgData *argData);
9956     HRESULT SendCleanup();
9957
9958     // Create a RS literal for primitive type funceval result. In case the result is used as an argument for
9959     // another funceval, we need to make sure that we're not relying on the LS value, which will be freed and
9960     // thus unavailable. 
9961     HRESULT CreatePrimitiveLiteral(CordbType *       pType,
9962                                    ICorDebugValue ** ppValue);
9963
9964     //-----------------------------------------------------------
9965     // Data members
9966     //-----------------------------------------------------------
9967
9968     bool IsEvalDuringException() { return m_evalDuringException; }
9969 private:
9970     // We must keep a strong reference to the thread so we can properly fail out of SendCleanup if someone releases an
9971     // ICorDebugEval after the process has completely gone away. 
9972     RSSmartPtr<CordbThread>    m_thread;
9973     
9974     CordbFunction             *m_function;
9975     CordbClass                *m_class;
9976     DebuggerIPCE_FuncEvalType  m_evalType;
9977
9978     HRESULT SendFuncEval(unsigned int genericArgsCount, ICorDebugType *genericArgs[], void *argData1, unsigned int argData1Size, void *argData2, unsigned int argData2Size, DebuggerIPCEvent * event);
9979     HRESULT FilterHR(HRESULT hr);
9980     BOOL DoAppDomainsMatch( CordbAppDomain* pAppDomain, ULONG32 nTypes, ICorDebugType *pTypes[], ULONG32 nValues, ICorDebugValue *pValues[] );
9981
9982 public:
9983     bool                       m_complete;
9984     bool                       m_successful;
9985     bool                       m_aborted;
9986     void                      *m_resultAddr;
9987
9988     // This is an OBJECTHANDLE on the LS if func-eval creates a strong handle.
9989     // This is a resource in the left-side and must be cleaned up in the left-side.
9990     // This gets handled off to a CordbHandleValue (m_pHandleValue) once code:CordbEval::GetResult
9991     // and then the CordbHandle is responsible for releasing it in the left-side.
9992     // Issue!! This will be leaked if nobody calls GetResult().
9993     VMPTR_OBJECTHANDLE         m_vmObjectHandle;          
9994
9995     // This is the corresponding cached CordbHandleValue for GetResult.
9996     // This takes ownership of the strong handle, m_objectHandle. 
9997     // This is an External reference, which keeps the Value from being neutered
9998     // on a NeuterAtWill sweep.
9999     RSExtSmartPtr<CordbHandleValue> m_pHandleValue;          
10000
10001     DebuggerIPCE_ExpandedTypeData m_resultType;
10002     VMPTR_AppDomain            m_resultAppDomainToken;
10003
10004     // Left-side memory that needs to be freed.
10005     LSPTR_DEBUGGEREVAL         m_debuggerEvalKey;
10006
10007
10008     // If we're evalling during a thread's exception, remember the info so that we can restore it when we're done.
10009     bool                       m_evalDuringException;     // flag whether we're during the thread's exception.
10010     VMPTR_OBJECTHANDLE  m_vmThreadOldExceptionHandle; // object handle for thread's managed exception object.
10011
10012 #ifdef _DEBUG
10013     // Func-eval should perturb the the thread's current appdomain. So we remember it at start
10014     // and then ensure that the func-eval complete restores it.
10015     CordbAppDomain *           m_DbgAppDomainStarted;
10016 #endif
10017 };
10018
10019
10020 /* ------------------------------------------------------------------------- *
10021  * Win32 Event Thread class
10022  * ------------------------------------------------------------------------- */
10023 const unsigned int CW32ET_UNKNOWN_PROCESS_SLOT = 0xFFffFFff; // it's a managed process,
10024         //but we don't know which slot it's in - for Detach.
10025
10026 //---------------------------------------------------------------------------------------
10027 //
10028 // Dedicated thread for win32 debugging operations.
10029 //
10030 // Notes:
10031 //    This is owned by the ShimProcess object. That will both create this and destroy it.
10032 //    OS restriction is that all win32 debugging APIs (CreateProcess, DebugActiveProcess,
10033 //    DebugActiveProcessStop, WaitForDebugEvent, ContinueDebugEvent, etc) are on the same thread.
10034 //
10035 class CordbWin32EventThread
10036 {
10037     friend class CordbProcess; //so that Detach can call ExitProcess
10038 public:
10039     CordbWin32EventThread(Cordb * pCordb, ShimProcess * pShim);
10040     virtual ~CordbWin32EventThread();
10041
10042     //
10043     // You create a new instance of this class, call Init() to set it up,
10044     // then call Start() start processing events. Stop() terminates the
10045     // thread and deleting the instance cleans all the handles and such
10046     // up.
10047     //
10048     HRESULT Init();
10049     HRESULT Start();
10050     HRESULT Stop();
10051
10052     HRESULT SendCreateProcessEvent(MachineInfo machineInfo,
10053                                    LPCWSTR programName,
10054                                    __in_z LPWSTR  programArgs,
10055                                    LPSECURITY_ATTRIBUTES lpProcessAttributes,
10056                                    LPSECURITY_ATTRIBUTES lpThreadAttributes,
10057                                    BOOL bInheritHandles,
10058                                    DWORD dwCreationFlags,
10059                                    PVOID lpEnvironment,
10060                                    LPCWSTR lpCurrentDirectory,
10061                                    LPSTARTUPINFOW lpStartupInfo,
10062                                    LPPROCESS_INFORMATION lpProcessInformation,
10063                                    CorDebugCreateProcessFlags corDebugFlags);
10064
10065     HRESULT SendDebugActiveProcessEvent(MachineInfo machineInfo,
10066                                         DWORD pid,
10067                                         bool fWin32Attach,
10068                                         CordbProcess *pProcess);
10069
10070     HRESULT SendDetachProcessEvent(CordbProcess *pProcess);
10071
10072 #ifdef FEATURE_INTEROP_DEBUGGING
10073     HRESULT SendUnmanagedContinue(CordbProcess *pProcess,
10074                                   EUMContinueType eContType);
10075     HRESULT UnmanagedContinue(CordbProcess *pProcess,
10076                               EUMContinueType eContType);
10077     void DoDbgContinue(CordbProcess * pProcess,
10078                        CordbUnmanagedEvent * pUnmanagedEvent);
10079     void ForceDbgContinue(CordbProcess *pProcess,
10080                           CordbUnmanagedThread *ut,
10081                           DWORD contType,
10082                           bool contProcess);
10083
10084 #endif //FEATURE_INTEROP_DEBUGGING
10085
10086     void LockSendToWin32EventThreadMutex()
10087     {
10088         LOG((LF_CORDB, LL_INFO10000, "W32ET::LockSendToWin32EventThreadMutex\n"));
10089         m_sendToWin32EventThreadMutex.Lock();
10090     }
10091
10092     void UnlockSendToWin32EventThreadMutex()
10093     {
10094         m_sendToWin32EventThreadMutex.Unlock();
10095         LOG((LF_CORDB, LL_INFO10000, "W32ET::UnlockSendToWin32EventThreadMutex\n"));
10096     }
10097
10098     bool IsWin32EventThread()
10099     {
10100         return (m_threadId == GetCurrentThreadId());
10101     }
10102
10103     void Win32EventLoop();
10104
10105
10106     INativeEventPipeline * GetNativePipeline();
10107 private:
10108     void ThreadProc();
10109     static DWORD WINAPI ThreadProc(LPVOID parameter);
10110
10111     void CreateProcess();
10112
10113
10114     INativeEventPipeline * m_pNativePipeline;
10115
10116
10117     void AttachProcess();
10118
10119     void HandleUnmanagedContinue();
10120
10121     void ExitProcess(bool fDetach);
10122
10123 private:
10124     RSSmartPtr<Cordb>    m_cordb;
10125
10126     HANDLE               m_thread;
10127     DWORD                m_threadId;
10128     HANDLE               m_threadControlEvent;
10129     HANDLE               m_actionTakenEvent;
10130     BOOL                 m_run;
10131
10132     // The process that we're 1:1 with.
10133     // This is set when we get a Create / Attach event.
10134     // This is only used on the W32ET, which guarantees it will free of races.
10135     RSSmartPtr<CordbProcess> m_pProcess;
10136
10137
10138     ShimProcess * m_pShim;
10139
10140     // @todo - convert this into Stop-Go lock?
10141     RSLock               m_sendToWin32EventThreadMutex;
10142
10143     unsigned int         m_action;
10144     HRESULT              m_actionResult;
10145     union
10146     {
10147         struct
10148         {
10149             MachineInfo machineInfo;
10150             LPCWSTR programName;
10151             LPWSTR  programArgs;
10152             LPSECURITY_ATTRIBUTES lpProcessAttributes;
10153             LPSECURITY_ATTRIBUTES lpThreadAttributes;
10154             BOOL bInheritHandles;
10155             DWORD dwCreationFlags;
10156             PVOID lpEnvironment;
10157             LPCWSTR lpCurrentDirectory;
10158             LPSTARTUPINFOW lpStartupInfo;
10159             LPPROCESS_INFORMATION lpProcessInformation;
10160             CorDebugCreateProcessFlags corDebugFlags;
10161         } createData;
10162
10163         struct
10164         {
10165             MachineInfo     machineInfo;
10166             DWORD           processId;
10167 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
10168             bool            fWin32Attach;
10169 #endif
10170             CordbProcess    *pProcess;
10171
10172             // Wrapper to determine if we're interop-debugging.
10173             bool IsInteropDebugging()
10174             {
10175 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
10176                 return fWin32Attach;
10177 #else
10178                 return false;
10179 #endif
10180             }
10181         } attachData;
10182
10183         struct
10184         {
10185             CordbProcess    *pProcess;
10186         } detachData;
10187
10188         struct
10189         {
10190             CordbProcess *process;
10191             EUMContinueType eContType;
10192         } continueData;
10193     }                    m_actionData;
10194 };
10195
10196
10197 // Thread-safe stack which.
10198 template <typename T>
10199 class InterlockedStack
10200 {
10201 public:
10202     InterlockedStack();
10203     ~InterlockedStack();
10204
10205     // Thread safe pushes + pops.
10206     // Many threads can push simultaneously.
10207     // Only 1 thread can pop.
10208     void Push(T * pItem);
10209     T * Pop();
10210
10211 protected:
10212     T * m_pHead;
10213 };
10214
10215 //-----------------------------------------------------------------------------
10216 // Workitem to be placed on RCET worker queue.
10217 // There's 1 RCET for to be shared by all processes.
10218 //-----------------------------------------------------------------------------
10219 class RCETWorkItem
10220 {
10221 public:
10222
10223     virtual ~RCETWorkItem() {}
10224     
10225     // Item is executed and then removed from the list and deleted.
10226     virtual void Do() = 0;
10227
10228     CordbProcess * GetProcess() { return m_pProcess; }
10229
10230 protected:
10231     RCETWorkItem(CordbProcess * pProcess)
10232     {
10233         m_pProcess.Assign(pProcess);
10234         m_next = NULL;
10235     }
10236
10237     RSSmartPtr<CordbProcess> m_pProcess;
10238
10239     // This field is accessed by the InterlockedStack.
10240     friend class InterlockedStack<RCETWorkItem>;
10241     RCETWorkItem * m_next;
10242 };
10243
10244
10245 // Item to do Neutering work on ExitProcess.
10246 class ExitProcessWorkItem : public RCETWorkItem
10247 {
10248 public:
10249     ExitProcessWorkItem(CordbProcess * pProc) : RCETWorkItem(pProc)
10250     {
10251     }
10252
10253     virtual void Do();
10254 };
10255
10256 // Item to do send Attach event.
10257 class SendAttachProcessWorkItem : public RCETWorkItem
10258 {
10259 public:
10260     SendAttachProcessWorkItem(CordbProcess * pProc) : RCETWorkItem(pProc)
10261     {
10262     }
10263
10264     virtual void Do();
10265 };
10266
10267
10268 /* ------------------------------------------------------------------------- *
10269  * Runtime Controller Event Thread class
10270  * ------------------------------------------------------------------------- */
10271
10272 class CordbRCEventThread
10273 {
10274 public:
10275     CordbRCEventThread(Cordb* cordb);
10276     virtual ~CordbRCEventThread();
10277
10278     //
10279     // You create a new instance of this class, call Init() to set it up,
10280     // then call Start() start processing events. Stop() terminates the
10281     // thread and deleting the instance cleans all the handles and such
10282     // up.
10283     //
10284     HRESULT Init();
10285     HRESULT Start();
10286     HRESULT Stop();
10287
10288     // RCET will take ownership of this item and delete it.
10289     void QueueAsyncWorkItem(RCETWorkItem * pItem);
10290
10291     HRESULT SendIPCEvent(CordbProcess* process,
10292                          DebuggerIPCEvent* event,
10293                          SIZE_T eventSize);
10294
10295     void ProcessStateChanged();
10296     void FlushQueuedEvents(CordbProcess* process);
10297
10298     HRESULT WaitForIPCEventFromProcess(CordbProcess* process,
10299                                        CordbAppDomain *pAppDomain,
10300                                        DebuggerIPCEvent* event);
10301
10302     bool IsRCEventThread();
10303
10304 private:
10305     void DrainWorkerQueue();
10306
10307     void ThreadProc();
10308     static DWORD WINAPI ThreadProc(LPVOID parameter);
10309
10310
10311 private:
10312     InterlockedStack<class RCETWorkItem> m_WorkerStack;
10313
10314     RSSmartPtr<Cordb>    m_cordb;
10315     HANDLE               m_thread;
10316     DWORD                m_threadId;
10317     BOOL                 m_run;
10318     HANDLE               m_threadControlEvent;
10319     BOOL                 m_processStateChanged;
10320 };
10321
10322 #ifdef FEATURE_INTEROP_DEBUGGING
10323 /* ------------------------------------------------------------------------- *
10324  * Unmanaged Event struct
10325  * ------------------------------------------------------------------------- */
10326
10327 enum CordbUnmanagedEventState
10328 {
10329
10330     // The continued flags get set in one of a few patterns.
10331     // 1) The event is continued having never been hijacked =>
10332     //      EventContinuedUnhijacked is set
10333     // 2) The event is continued having been hijacked and then the process terminates or
10334     //    an error occurs before the hijack finishes =>
10335     //      EventContinuedHijacked is set
10336     // 3) The event is continued having been hijacked, then the hijack completes and
10337     //    execution resumes in the debuggee
10338     //      EventContinuedHijacked is set
10339     //      EventContinuedUnhijacked is set
10340
10341     CUES_None                     = 0x00,
10342     CUES_ExceptionCleared         = 0x01,
10343     CUES_EventContinuedHijacked   = 0x02,
10344     CUES_EventContinuedUnhijacked = 0x04,
10345     CUES_Dispatched               = 0x08,
10346     CUES_ExceptionUnclearable     = 0x10,
10347
10348     // This is set when a user continues the event by calling
10349     // Continue()
10350     CUES_UserContinued            = 0x20,
10351     // This is true if the event is an IB event
10352     CUES_IsIBEvent                = 0x40,
10353 };
10354
10355 struct CordbUnmanagedEvent
10356 {
10357 public:
10358     BOOL IsExceptionCleared() { return m_state & CUES_ExceptionCleared; }
10359     BOOL IsEventContinuedHijacked() { return m_state & CUES_EventContinuedHijacked; }
10360     BOOL IsEventContinuedUnhijacked() { return m_state & CUES_EventContinuedUnhijacked; }
10361     BOOL IsEventUserContinued() { return m_state & CUES_UserContinued; }
10362     BOOL IsEventWaitingForContinue()
10363     {
10364         return (!IsEventContinuedHijacked() && !IsEventContinuedUnhijacked());
10365     }
10366     BOOL IsDispatched() { return m_state & CUES_Dispatched; }
10367     BOOL IsExceptionUnclearable() { return m_state & CUES_ExceptionUnclearable; }
10368     BOOL IsIBEvent() { return m_state & CUES_IsIBEvent; }
10369
10370     void SetState(CordbUnmanagedEventState state) { m_state = (CordbUnmanagedEventState)(m_state | state); }
10371     void ClearState(CordbUnmanagedEventState state) { m_state = (CordbUnmanagedEventState)(m_state & ~state); }
10372
10373     CordbUnmanagedThread     *m_owner;
10374     CordbUnmanagedEventState  m_state;
10375     DEBUG_EVENT               m_currentDebugEvent;
10376     CordbUnmanagedEvent      *m_next;
10377 };
10378
10379
10380 /* ------------------------------------------------------------------------- *
10381  * Unmanaged Thread class
10382  * ------------------------------------------------------------------------- */
10383
10384 enum CordbUnmanagedThreadState
10385 {
10386     CUTS_None                        = 0x0000,
10387     CUTS_Deleted                     = 0x0001,
10388     CUTS_FirstChanceHijacked         = 0x0002,
10389     // Set when interop debugging needs the SS flag to be enabled
10390     // regardless of what the user wants it to be
10391     CUTS_IsSSFlagNeeded              = 0x0004,
10392     CUTS_GenericHijacked             = 0x0008,
10393     // when the m_raiseExceptionEntryContext is valid
10394     CUTS_HasRaiseExceptionEntryCtx   = 0x0010,
10395     CUTS_BlockingForSync             = 0x0020,
10396     CUTS_Suspended                   = 0x0040,
10397     CUTS_IsSpecialDebuggerThread     = 0x0080,
10398     // when the thread is re-executing RaiseException to retrigger an exception
10399     CUTS_IsRaiseExceptionHijacked    = 0x0100,
10400     CUTS_HasIBEvent                  = 0x0200,
10401     CUTS_HasOOBEvent                 = 0x0400,
10402     CUTS_HasSpecialStackOverflowCase = 0x0800,
10403 #ifdef _DEBUG
10404     CUTS_DEBUG_SingleStep            = 0x1000,
10405 #endif
10406     CUTS_SkippingNativePatch         = 0x2000,
10407     CUTS_HasContextSet               = 0x4000,
10408     // Set when interop debugging is making use of the single step flag
10409     // but the user has not set it
10410     CUTS_IsSSFlagHidden              = 0x8000
10411     
10412 };
10413
10414 class CordbUnmanagedThread : public CordbBase
10415 {
10416 public:
10417     CordbUnmanagedThread(CordbProcess *pProcess, DWORD dwThreadId, HANDLE hThread, void *lpThreadLocalBase);
10418     ~CordbUnmanagedThread();
10419
10420     using CordbBase::GetProcess;
10421
10422 #ifdef _DEBUG
10423     virtual const char * DbgGetName() { return "CordbUnmanagedThread"; }
10424 #endif
10425
10426     // CordbUnmanagedThread is a purely internal object. It's not exposed via ICorDebug APIs and so
10427     // we should never use External AddRef.
10428     ULONG STDMETHODCALLTYPE AddRef() { _ASSERTE(!"Don't use external addref on a CordbUnmanagedThread"); return (BaseAddRef());}
10429     ULONG STDMETHODCALLTYPE Release() { _ASSERTE(!"Don't use external release on a CordbUnmanagedThread"); return (BaseRelease());}
10430
10431     COM_METHOD QueryInterface(REFIID riid, void **ppInterface)
10432     {
10433         _ASSERTE(!"Don't use QI on a CordbUnmanagedThread");
10434         // Not really used since we never expose this class. If we ever do expose this class via the ICorDebug API then
10435         // we should, of course, implement this.
10436         return E_NOINTERFACE;
10437     }
10438
10439     HRESULT LoadTLSArrayPtr();
10440
10441     // Hijacks this thread to a hijack worker function which recieves the current
10442     // context and the provided exception record. The reason determines what code
10443     // the hijack worker executes
10444     HRESULT SetupFirstChanceHijack(EHijackReason::EHijackReason reason, const EXCEPTION_RECORD * pExceptionRecord);
10445     HRESULT SetupFirstChanceHijackForSync();
10446
10447     HRESULT SetupGenericHijack(DWORD eventCode, const EXCEPTION_RECORD * pRecord);
10448     HRESULT FixupFromGenericHijack();
10449
10450     HRESULT FixupAfterOOBException(CordbUnmanagedEvent * ue);
10451
10452     void SetupForSkipBreakpoint(NativePatch * pNativePatch);
10453     void FixupForSkipBreakpoint();
10454     bool IsCantStop();
10455
10456     // These are wrappers for the OS calls which hide
10457     // the effects of hijacking and internal SS flag usage
10458     HRESULT GetThreadContext(DT_CONTEXT * pContext);
10459     HRESULT SetThreadContext(DT_CONTEXT * pContext);
10460
10461     // Turns on and off the internal usage of the SS flag
10462     VOID BeginStepping();
10463     VOID EndStepping();
10464
10465     // An accessor for &m_context, this value generally stores
10466     // a context we may need to restore after a hijack completes
10467     DT_CONTEXT * GetHijackCtx();
10468
10469 private:
10470     CORDB_ADDRESS m_stackBase;
10471     CORDB_ADDRESS m_stackLimit;
10472
10473 public:
10474     BOOL GetStackRange(CORDB_ADDRESS *pBase, CORDB_ADDRESS *pLimit);
10475
10476     BOOL IsDeleted() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_Deleted; }
10477     BOOL IsFirstChanceHijacked() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_FirstChanceHijacked; }
10478     BOOL IsGenericHijacked() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_GenericHijacked; }
10479     BOOL IsBlockingForSync() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_BlockingForSync; }
10480     BOOL IsSuspended() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_Suspended; }
10481     BOOL IsSpecialDebuggerThread() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_IsSpecialDebuggerThread; }
10482     BOOL HasIBEvent() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_HasIBEvent; }
10483     BOOL HasOOBEvent() { return m_state & CUTS_HasOOBEvent; }
10484     BOOL HasSpecialStackOverflowCase() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_HasSpecialStackOverflowCase; }
10485 #ifdef _DEBUG
10486     BOOL IsDEBUGTrace() { return m_state & CUTS_DEBUG_SingleStep; }
10487 #endif
10488     BOOL IsSkippingNativePatch() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_SkippingNativePatch; }
10489     BOOL IsContextSet() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_HasContextSet; }
10490     BOOL IsSSFlagNeeded() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_IsSSFlagNeeded; }
10491     BOOL IsSSFlagHidden() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_IsSSFlagHidden; }
10492     BOOL HasRaiseExceptionEntryCtx() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_HasRaiseExceptionEntryCtx; }
10493     BOOL IsRaiseExceptionHijacked() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_IsRaiseExceptionHijacked; }
10494
10495     void SetState(CordbUnmanagedThreadState state) 
10496     {
10497         LIMITED_METHOD_CONTRACT;  
10498         m_state = (CordbUnmanagedThreadState)(m_state | state); 
10499         _ASSERTE(!IsSuspended() || !IsBlockingForSync());
10500         _ASSERTE(!IsSuspended() || !IsFirstChanceHijacked());
10501     }
10502     void ClearState(CordbUnmanagedThreadState state) {LIMITED_METHOD_CONTRACT;  m_state = (CordbUnmanagedThreadState)(m_state & ~state); }
10503
10504     void HijackToRaiseException();
10505     void RestoreFromRaiseExceptionHijack();
10506     void SaveRaiseExceptionEntryContext();
10507     void ClearRaiseExceptionEntryContext();
10508     BOOL IsExceptionFromLastRaiseException(const EXCEPTION_RECORD* pExceptionRecord);
10509
10510     CordbUnmanagedEvent *IBEvent()  {LIMITED_METHOD_CONTRACT;  return &m_IBEvent; }
10511     CordbUnmanagedEvent *IBEvent2() {LIMITED_METHOD_CONTRACT;  return &m_IBEvent2; }
10512     CordbUnmanagedEvent *OOBEvent() { return &m_OOBEvent; }
10513
10514     DWORD GetOSTid() 
10515     { 
10516         return (DWORD) this->m_id; 
10517     }
10518
10519 #ifdef DBG_TARGET_X86
10520     // Stores the thread's current leaf SEH handler
10521     HRESULT SaveCurrentLeafSeh();
10522     // Restores the thread's leaf SEH handler from the previously saved value
10523     HRESULT RestoreLeafSeh();
10524 #endif
10525
10526     // Logs basic data about a context to the debugging log
10527     static VOID LogContext(DT_CONTEXT* pContext);
10528
10529 public:
10530     HANDLE                     m_handle;
10531
10532     // @dbgtodo - the TLS reading is only used for interop hijacks; which goes away in Arrowhead.
10533     // Target address of the Thread Information Block (TIB).
10534     void                      *m_threadLocalBase;
10535     
10536     // Target address of the Thread Local Storage (TLS) array. This is for slots 0 -63.
10537     void                      *m_pTLSArray;
10538
10539     // Target Address of extended Thread local Storage array. These are for slots about 63.
10540     // This may be NULL if extended storage is not yet allocated.
10541     void                      *m_pTLSExtendedArray;
10542
10543
10544     CordbUnmanagedThreadState  m_state;
10545
10546     CordbUnmanagedEvent        m_IBEvent;
10547     CordbUnmanagedEvent        m_IBEvent2;
10548     CordbUnmanagedEvent        m_OOBEvent;
10549
10550     LSPTR_CONTEXT              m_pLeftSideContext;
10551     void                      *m_originalHandler;
10552
10553 private:
10554     // Spare context used for various purposes. 
10555     // See CordbUnmanagedThread::GetThreadContext for details
10556     DT_CONTEXT                 m_context;
10557
10558     // The context of the thread the last time it called into kernel32!RaiseException
10559     DT_CONTEXT                 m_raiseExceptionEntryContext;
10560
10561     DWORD                      m_raiseExceptionExceptionCode;
10562     DWORD                      m_raiseExceptionExceptionFlags;
10563     DWORD                      m_raiseExceptionNumberParameters;
10564     ULONG_PTR                  m_raiseExceptionExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
10565
10566
10567 #ifdef DBG_TARGET_X86
10568     // the SEH handler which was the leaf when SaveCurrentSeh was called (prior to hijack)
10569     REMOTE_PTR                 m_pSavedLeafSeh;
10570 #endif
10571
10572     HRESULT EnableSSAfterBP();
10573     bool GetEEThreadCantStopHelper();
10574
10575     DWORD_PTR GetTlsSlot(SIZE_T slot);
10576     REMOTE_PTR GetPreDefTlsSlot(SIZE_T slot, bool * pRead);
10577
10578     void * m_pPatchSkipAddress;
10579
10580
10581
10582     /* 
10583      * This abstracts away an overload of the OS thread's TLS slot. In 
10584      * particular the runtime may or may not have created a thread object for
10585      * a particular OS thread at any point.
10586      *
10587      * If the runtime has created a thread object, then it stores a pointer to
10588      * that thread object in the thread's TLS slot.
10589      *
10590      * If not, then interop-debugging uses that TLS slot to store temporary 
10591      * information.
10592      *
10593      * To determine this, interop-debugging will set the low bit.  Thus when
10594      * we read the TLS slot, if it is non-NULL, anything w/o the low bit set
10595      * is an EE thread object ptr.  Anything with the low bit set is an 
10596      * interop-debugging value.  Any NULL is null, and an indicator that 
10597      * there does not exist a runtime thread object for this thread yet.
10598      *
10599      */
10600     REMOTE_PTR m_pEEThread;
10601     REMOTE_PTR m_pdwTlsValue;
10602     BOOL m_fValidTlsData;
10603
10604     UINT m_continueCountCached;
10605
10606     void CacheEEDebuggerWord();
10607     HRESULT SetEEThreadValue(REMOTE_PTR EETlsValue);
10608 #ifdef FEATURE_IMPLICIT_TLS
10609     DWORD_PTR GetEEThreadValue();
10610     REMOTE_PTR GetClrModuleTlsDataAddress();
10611     REMOTE_PTR GetEETlsDataBlock();
10612 #endif
10613
10614 public:
10615     HRESULT GetEEDebuggerWord(REMOTE_PTR *pValue);
10616     HRESULT SetEEDebuggerWord(REMOTE_PTR value);
10617     HRESULT GetEEThreadPtr(REMOTE_PTR *ppEEThread);
10618     
10619     bool GetEEPGCDisabled();
10620     void GetEEState(bool *threadStepping, bool *specialManagedException);
10621     bool GetEEFrame();
10622 };
10623 #endif // FEATURE_INTEROP_DEBUGGING
10624
10625
10626 //********************************************************************************
10627 //**************** App Domain Publishing Service API *****************************
10628 //********************************************************************************
10629
10630
10631 class EnumElement
10632 {
10633 public:
10634     EnumElement()
10635     {
10636         m_pData = NULL;
10637         m_pNext = NULL;
10638     }
10639
10640     void SetData (void *pData) { m_pData = pData;}
10641     void *GetData () { return m_pData;}
10642     void SetNext (EnumElement *pNext) { m_pNext = pNext;}
10643     EnumElement *GetNext () { return m_pNext;}
10644
10645 private:
10646     void        *m_pData;
10647     EnumElement *m_pNext;
10648 };
10649
10650 #if defined(FEATURE_DBG_PUBLISH)
10651
10652 // Prototype of psapi!GetModuleFileNameEx.
10653 typedef DWORD FPGetModuleFileNameEx(HANDLE, HMODULE, LPTSTR, DWORD);
10654
10655
10656 class CorpubPublish : public CordbCommonBase, public ICorPublish
10657 {
10658 public:
10659     CorpubPublish();
10660     virtual ~CorpubPublish();
10661
10662 #ifdef _DEBUG
10663     virtual const char * DbgGetName() { return "CordbPublish"; }
10664 #endif
10665
10666     //-----------------------------------------------------------
10667     // IUnknown
10668     //-----------------------------------------------------------
10669
10670     ULONG STDMETHODCALLTYPE AddRef()
10671     {
10672         return (BaseAddRef());
10673     }
10674     ULONG STDMETHODCALLTYPE Release()
10675     {
10676         return (BaseRelease());
10677     }
10678     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10679
10680     //-----------------------------------------------------------
10681     // ICorPublish
10682     //-----------------------------------------------------------
10683
10684     COM_METHOD EnumProcesses(
10685         COR_PUB_ENUMPROCESS Type,
10686         ICorPublishProcessEnum **ppIEnum);
10687
10688     COM_METHOD GetProcess(
10689         unsigned pid,
10690         ICorPublishProcess **ppProcess);
10691
10692     //-----------------------------------------------------------
10693     // CreateObject
10694     //-----------------------------------------------------------
10695     static COM_METHOD CreateObject(REFIID id, void **object)
10696     {
10697         *object = NULL;
10698
10699         if (id != IID_IUnknown && id != IID_ICorPublish)
10700             return (E_NOINTERFACE);
10701
10702         CorpubPublish *pCorPub = new (nothrow) CorpubPublish();
10703
10704         if (pCorPub == NULL)
10705             return (E_OUTOFMEMORY);
10706
10707         *object = (ICorPublish*)pCorPub;
10708         pCorPub->AddRef();
10709
10710         return (S_OK);
10711     }
10712
10713 private:
10714     HRESULT GetProcessInternal( unsigned pid, CorpubProcess **ppProcess );
10715
10716     // Cached information to get the process name. Not available on all platforms, so may be null.
10717     HModuleHolder m_hPSAPIdll;
10718     FPGetModuleFileNameEx * m_fpGetModuleFileNameEx;
10719 };
10720
10721 class CorpubProcess : public CordbCommonBase, public ICorPublishProcess
10722 {
10723 public:
10724     CorpubProcess(DWORD dwProcessId, 
10725         bool fManaged, 
10726         HANDLE hProcess,
10727         HANDLE hMutex, 
10728         AppDomainEnumerationIPCBlock *pAD, 
10729 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
10730         IPCReaderInterface *pIPCReader, 
10731 #endif // !FEATURE_DBGIPC_TRANSPORT_DI
10732         FPGetModuleFileNameEx * fpGetModuleFileNameEx);
10733     virtual ~CorpubProcess();
10734
10735 #ifdef _DEBUG
10736     virtual const char * DbgGetName() { return "CorpubProcess"; }
10737 #endif
10738
10739
10740     //-----------------------------------------------------------
10741     // IUnknown
10742     //-----------------------------------------------------------
10743
10744     ULONG STDMETHODCALLTYPE AddRef()
10745     {
10746         return (BaseAddRef());
10747     }
10748     ULONG STDMETHODCALLTYPE Release()
10749     {
10750         return (BaseRelease());
10751     }
10752     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10753
10754     //-----------------------------------------------------------
10755     // ICorPublishProcess
10756     //-----------------------------------------------------------
10757     COM_METHOD IsManaged(BOOL *pbManaged);
10758
10759     /*
10760      * Enumerate the list of known application domains in the target process.
10761      */
10762     COM_METHOD EnumAppDomains(ICorPublishAppDomainEnum **ppEnum);
10763
10764     /*
10765      * Returns the OS ID for the process in question.
10766      */
10767     COM_METHOD GetProcessID(unsigned *pid);
10768
10769     /*
10770      * Get the display name for a process.
10771      */
10772     COM_METHOD GetDisplayName(ULONG32 cchName,
10773                                 ULONG32 *pcchName,
10774                                 __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
10775
10776     CorpubProcess   *GetNextProcess () { return m_pNext;}
10777     void SetNext (CorpubProcess *pNext) { m_pNext = pNext;}
10778
10779     // Helper to tell if this process has exited
10780     bool IsExited();
10781
10782 public:
10783     DWORD                           m_dwProcessId;
10784
10785 private:
10786     bool                            m_fIsManaged;
10787     HANDLE                          m_hProcess;
10788     HANDLE                          m_hMutex;
10789     AppDomainEnumerationIPCBlock    *m_AppDomainCB;
10790 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
10791     IPCReaderInterface              *m_pIPCReader;  // controls the lifetime of the AppDomainEnumerationIPCBlock
10792 #endif // !FEATURE_DBGIPC_TRANSPORT_DI
10793     CorpubProcess                   *m_pNext;   // pointer to the next process in the process list
10794     WCHAR                           *m_szProcessName;
10795
10796 };
10797
10798 class CorpubAppDomain  : public CordbCommonBase, public ICorPublishAppDomain
10799 {
10800 public:
10801     CorpubAppDomain (__in LPWSTR szAppDomainName, ULONG Id);
10802     virtual ~CorpubAppDomain();
10803
10804 #ifdef _DEBUG
10805     virtual const char * DbgGetName() { return "CorpubAppDomain"; }
10806 #endif
10807
10808     //-----------------------------------------------------------
10809     // IUnknown
10810     //-----------------------------------------------------------
10811
10812     ULONG STDMETHODCALLTYPE AddRef()
10813     {
10814         return (BaseAddRef());
10815     }
10816     ULONG STDMETHODCALLTYPE Release()
10817     {
10818         return (BaseRelease());
10819     }
10820     COM_METHOD QueryInterface (REFIID riid, void **ppInterface);
10821
10822     //-----------------------------------------------------------
10823     // ICorPublishAppDomain
10824     //-----------------------------------------------------------
10825
10826     /*
10827      * Get the name and ID for an application domain.
10828      */
10829     COM_METHOD GetID (ULONG32 *pId);
10830
10831     /*
10832      * Get the name for an application domain.
10833      */
10834     COM_METHOD GetName (ULONG32 cchName,
10835                         ULONG32 *pcchName,
10836                         __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
10837
10838     CorpubAppDomain *GetNextAppDomain () { return m_pNext;}
10839     void SetNext (CorpubAppDomain *pNext) { m_pNext = pNext;}
10840
10841 private:
10842     CorpubAppDomain *m_pNext;
10843     WCHAR           *m_szAppDomainName;
10844     ULONG           m_id;
10845
10846 };
10847
10848 class CorpubProcessEnum : public CordbCommonBase, public ICorPublishProcessEnum
10849 {
10850 public:
10851     CorpubProcessEnum(CorpubProcess *pFirst);
10852     virtual ~CorpubProcessEnum();
10853
10854 #ifdef _DEBUG
10855     virtual const char * DbgGetName() { return "CorpubProcessEnum"; }
10856 #endif
10857
10858
10859     //-----------------------------------------------------------
10860     // IUnknown
10861     //-----------------------------------------------------------
10862
10863     ULONG STDMETHODCALLTYPE AddRef()
10864     {
10865         return (BaseAddRef());
10866     }
10867     ULONG STDMETHODCALLTYPE Release()
10868     {
10869         return (BaseRelease());
10870     }
10871     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10872
10873     //-----------------------------------------------------------
10874     // ICorPublishProcessEnum
10875     //-----------------------------------------------------------
10876
10877     COM_METHOD Skip(ULONG celt);
10878     COM_METHOD Reset();
10879     COM_METHOD Clone(ICorPublishEnum **ppEnum);
10880     COM_METHOD GetCount(ULONG *pcelt);
10881     COM_METHOD Next(ULONG celt,
10882                     ICorPublishProcess *objects[],
10883                     ULONG *pceltFetched);
10884
10885 private:
10886     CorpubProcess       *m_pFirst;
10887     CorpubProcess       *m_pCurrent;
10888
10889 };
10890
10891 class CorpubAppDomainEnum : public CordbCommonBase, public ICorPublishAppDomainEnum
10892 {
10893 public:
10894     CorpubAppDomainEnum(CorpubAppDomain *pFirst);
10895     virtual ~CorpubAppDomainEnum();
10896
10897
10898 #ifdef _DEBUG
10899     virtual const char * DbgGetName() { return "CordbAppDomainEnum"; }
10900 #endif
10901
10902
10903     //-----------------------------------------------------------
10904     // IUnknown
10905     //-----------------------------------------------------------
10906
10907     ULONG STDMETHODCALLTYPE AddRef()
10908     {
10909         return (BaseAddRef());
10910     }
10911     ULONG STDMETHODCALLTYPE Release()
10912     {
10913         return (BaseRelease());
10914     }
10915     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10916
10917     //-----------------------------------------------------------
10918     // ICorPublishAppDomainEnum
10919     //-----------------------------------------------------------
10920     COM_METHOD Skip(ULONG celt);
10921     COM_METHOD Reset();
10922     COM_METHOD Clone(ICorPublishEnum **ppEnum);
10923     COM_METHOD GetCount(ULONG *pcelt);
10924
10925     COM_METHOD Next(ULONG celt,
10926                     ICorPublishAppDomain *objects[],
10927                     ULONG *pceltFetched);
10928
10929 private:
10930     CorpubAppDomain     *m_pFirst;
10931     CorpubAppDomain     *m_pCurrent;
10932
10933 };
10934
10935 #endif // defined(FEATURE_DBG_PUBLISH)
10936
10937 class CordbHeapEnum : public CordbBase, public ICorDebugHeapEnum
10938 {
10939 public:
10940     CordbHeapEnum(CordbProcess *proc);
10941
10942 #ifdef _DEBUG
10943     virtual const char * DbgGetName() { return "CordbHeapEnum"; }
10944 #endif
10945
10946     //-----------------------------------------------------------
10947     // IUnknown
10948     //-----------------------------------------------------------
10949     ULONG STDMETHODCALLTYPE AddRef()
10950     {
10951         return (BaseAddRef());
10952     }
10953     ULONG STDMETHODCALLTYPE Release()
10954     {
10955         return (BaseRelease());
10956     }
10957     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10958
10959     COM_METHOD Skip(ULONG celt);
10960     COM_METHOD Reset();
10961     COM_METHOD Clone(ICorDebugEnum **ppEnum);
10962     COM_METHOD GetCount(ULONG *pcelt);
10963
10964     COM_METHOD Next(ULONG celt,
10965                     COR_HEAPOBJECT objects[],
10966                     ULONG *pceltFetched);
10967
10968     virtual void Neuter()
10969     {
10970         Clear();
10971         CordbBase::Neuter();
10972     }
10973 private:
10974     void Clear();
10975
10976 private:
10977     IDacDbiInterface::HeapWalkHandle mHeapHandle;
10978 };
10979
10980
10981 class CordbRefEnum : public CordbBase, public ICorDebugGCReferenceEnum
10982 {
10983 public:
10984     CordbRefEnum(CordbProcess *proc, BOOL walkWeakRefs);
10985     CordbRefEnum(CordbProcess *proc, CorGCReferenceType types);
10986
10987 #ifdef _DEBUG
10988     virtual const char * DbgGetName() { return "CordbHeapEnum"; }
10989 #endif
10990
10991     //-----------------------------------------------------------
10992     // IUnknown
10993     //-----------------------------------------------------------
10994     ULONG STDMETHODCALLTYPE AddRef()
10995     {
10996         return (BaseAddRef());
10997     }
10998     ULONG STDMETHODCALLTYPE Release()
10999     {
11000         return (BaseRelease());
11001     }
11002     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
11003
11004     COM_METHOD Skip(ULONG celt);
11005     COM_METHOD Reset();
11006     COM_METHOD Clone(ICorDebugEnum **ppEnum);
11007     COM_METHOD GetCount(ULONG *pcelt);
11008
11009     COM_METHOD Next(ULONG celt,
11010                     COR_GC_REFERENCE refs[],
11011                     ULONG *pceltFetched);
11012
11013     virtual void Neuter();
11014     
11015 private:
11016     RefWalkHandle mRefHandle;
11017     BOOL mEnumStacksFQ;
11018     UINT32 mHandleMask;
11019 };
11020
11021 // Since the hash table of modules is per app domain (and
11022 // threads is per process) (for fast lookup from the appdomain/process),
11023 // we need this wrapper
11024 // here which allows us to iterate through an assembly's
11025 // modules.  Is basically filters out modules/threads that aren't
11026 // in the assembly/appdomain. This slow & awkward for assemblies, but fast
11027 // for the common case - appdomain lookup.
11028 class CordbEnumFilter : public CordbBase,
11029                         public ICorDebugThreadEnum,
11030                         public ICorDebugModuleEnum
11031 {
11032 public:
11033     CordbEnumFilter(CordbBase * pOwnerObj, NeuterList * pOwnerList);
11034     CordbEnumFilter(CordbEnumFilter*src);
11035     virtual ~CordbEnumFilter();
11036
11037     virtual void Neuter();
11038
11039
11040 #ifdef _DEBUG
11041     virtual const char * DbgGetName() { return "CordbEnumFilter"; }
11042 #endif
11043
11044
11045     //-----------------------------------------------------------
11046     // IUnknown
11047     //-----------------------------------------------------------
11048
11049     ULONG STDMETHODCALLTYPE AddRef()
11050     {
11051         return (BaseAddRef());
11052     }
11053     ULONG STDMETHODCALLTYPE Release()
11054     {
11055         return (BaseRelease());
11056     }
11057     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
11058
11059     //-----------------------------------------------------------
11060     // Common methods
11061     //-----------------------------------------------------------
11062     COM_METHOD Skip(ULONG celt);
11063     COM_METHOD Reset();
11064     COM_METHOD Clone(ICorDebugEnum **ppEnum);
11065     COM_METHOD GetCount(ULONG *pcelt);
11066     //-----------------------------------------------------------
11067     // ICorDebugModuleEnum
11068     //-----------------------------------------------------------
11069     COM_METHOD Next(ULONG celt,
11070                     ICorDebugModule *objects[],
11071                     ULONG *pceltFetched);
11072
11073     //-----------------------------------------------------------
11074     // ICorDebugThreadEnum
11075     //-----------------------------------------------------------
11076     COM_METHOD Next(ULONG celt,
11077                     ICorDebugThread *objects[],
11078                     ULONG *pceltFetched);
11079
11080     HRESULT Init (ICorDebugModuleEnum *pModEnum, CordbAssembly *pAssembly);
11081     HRESULT Init (ICorDebugThreadEnum *pThreadEnum, CordbAppDomain *pAppDomain);
11082
11083
11084 private:
11085     HRESULT NextWorker(ULONG celt, ICorDebugModule *objects[], ULONG *pceltFetched);
11086     HRESULT NextWorker(ULONG celt,ICorDebugThread *objects[], ULONG *pceltFetched);
11087
11088     // Owning object is our link to the CordbProcess* tree. Never null until we're neutered.
11089     // NeuterList is related to the owning object. Need to cache it so that we can pass it on
11090     // to our clones.
11091     CordbBase *     m_pOwnerObj; // provides us w/ a CordbProcess*
11092     NeuterList *    m_pOwnerNeuterList;
11093
11094
11095     EnumElement *m_pFirst;
11096     EnumElement *m_pCurrent;
11097     int         m_iCount;
11098 };
11099
11100 // Helpers to double-check the RS results against DAC.
11101 #if defined(_DEBUG)
11102 void CheckAgainstDAC(CordbFunction * pFunc, void * pIP, mdMethodDef mdExpected);
11103 #endif
11104
11105 HRESULT CopyOutString(const WCHAR * pInputString, ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
11106
11107
11108
11109 inline UINT AllocCookieCordbEval(CordbProcess *pProc, CordbEval* p)
11110 {
11111     _ASSERTE(pProc->GetProcessLock()->HasLock());
11112     return pProc->m_EvalTable.Add(p);
11113 }
11114 inline CordbEval * UnwrapCookieCordbEval(CordbProcess *pProc, UINT cookie)
11115 {
11116     _ASSERTE(pProc->GetProcessLock()->HasLock());
11117     return pProc->m_EvalTable.LookupAndRemove(cookie);
11118 }
11119
11120
11121 // We defined this at the top of the file - undef it now so that we don't pollute other files.
11122 #undef CRITICAL_SECTION
11123
11124
11125 #ifdef RSCONTRACTS
11126
11127 //-----------------------------------------------------------------------------
11128 // For debug builds, we maintain some thread-state to track debug bits
11129 // to help us do some more aggressive asserts.
11130 //-----------------------------------------------------------------------------
11131
11132 class PublicAPIHolder;
11133 class PublicReentrantAPIHolder;
11134 class PublicCallbackHolder;
11135 class PublicDebuggerErrorCallbackHolder;
11136
11137 class DbgRSThread
11138 {
11139 public:
11140     friend class PublicAPIHolder;
11141     friend class PublicReentrantAPIHolder;
11142     friend class PublicCallbackHolder;
11143     friend class PublicDebuggerErrorCallbackHolder;
11144     friend class PrivateShimCallbackHolder;
11145
11146     DbgRSThread();
11147
11148     // The TLS slot that we'll put this thread object in.
11149     static DWORD s_TlsSlot;
11150
11151     static LONG s_Total; // Total count of thread objects
11152
11153     // Get a thread object for the current thread via a TLS lookup.
11154     static DbgRSThread * GetThread();
11155
11156     // Call during DllMain to release this.
11157     static DbgRSThread * Create()
11158     {
11159         InterlockedIncrement(&s_Total);
11160
11161         DbgRSThread * p = new (nothrow) DbgRSThread();
11162         BOOL f = TlsSetValue(s_TlsSlot, p);
11163         _ASSERT(f);
11164         return p;
11165     }
11166
11167     void Destroy()
11168     {
11169         InterlockedDecrement(&s_Total);
11170
11171         BOOL f = TlsSetValue(s_TlsSlot, NULL);
11172         _ASSERT(f);
11173
11174         delete this;
11175     }
11176
11177     // Return true if this thread is inside the RS.
11178     bool IsInRS() { return m_cInsideRS > 0; }
11179
11180     // Locking API..
11181     // These will assert if the operation is unsafe.
11182     void NotifyTakeLock(RSLock * pLock);
11183     void NotifyReleaseLock(RSLock * pLock);
11184
11185     // Used to map other resources (like thread access) into the lock hierachy.
11186     // Note this only effects lock leveling checks and doesn't effect HoldsAnyLock().
11187     void TakeVirtualLock(RSLock::ERSLockLevel level);
11188     void ReleaseVirtualLock(RSLock::ERSLockLevel level);
11189
11190     // return true if this thread is holding any RS locks. Useful to check on Public API transition boundaries.
11191     bool HoldsAnyDbgApiLocks() { return m_cTotalDbgApiLocks > 0; }
11192
11193     enum EThreadType
11194     {
11195         cOther,
11196         cW32ET
11197     };
11198     void SetThreadType(EThreadType e) { m_eThreadType = e; }
11199
11200     bool IsWin32EventThread() { return m_eThreadType == cW32ET; }
11201
11202     void SetUnrecoverableCallback(bool fIsUnrecoverableErrorCallback)
11203     {
11204         // Not reentrant.
11205         _ASSERTE(m_fIsUnrecoverableErrorCallback != fIsUnrecoverableErrorCallback);
11206
11207         m_fIsUnrecoverableErrorCallback = fIsUnrecoverableErrorCallback;
11208     }
11209
11210     inline void AssertThreadIsLockFree()
11211     {
11212         // If we're in an unrecoverable callback, we may hold locks.
11213         _ASSERTE(m_fIsUnrecoverableErrorCallback
11214             || !HoldsAnyDbgApiLocks() ||
11215             !"Thread should not have locks on public/internal transition");
11216     }
11217
11218 protected:
11219     EThreadType m_eThreadType;
11220
11221     // More debugging tidbits - tid that we're on, and a sanity checking cookie.
11222     DWORD m_tid;
11223     DWORD m_Cookie;
11224
11225     enum ECookie
11226     {
11227         COOKIE_VALUE = 0x12345678
11228     };
11229
11230
11231     // This tells us if the thread is currently in the scope of a PublicAPIHolder.
11232     int m_cInsideRS;
11233
11234     // This tells us if a thread is currently being dispatched via a callback.
11235     bool m_fIsInCallback;
11236
11237     // We explicitly track if this thread is in an unrecoverable error callback
11238     // b/c that will weaken some other asserts.
11239     // It would be nice to clean up the unrecoverable error callback and have it
11240     // behave like all the other callbacks. Then we can remove this.
11241     bool m_fIsUnrecoverableErrorCallback;
11242
11243     // Locking context. Used to tell what levels of locks we hold so we can determine if a lock is safe to take.
11244     int m_cLocks[RSLock::LL_MAX];
11245     int m_cTotalDbgApiLocks;
11246 };
11247
11248 //-----------------------------------------------------------------------------
11249 // Mark when we enter / exit public APIs
11250 //-----------------------------------------------------------------------------
11251
11252 // Holder for Non-reentrant Public API (this is the vast majority)
11253 class PublicAPIHolder
11254 {
11255 public:
11256     PublicAPIHolder()
11257     {
11258         // on entry
11259         DbgRSThread * pThread = DbgRSThread::GetThread();
11260         pThread->m_cInsideRS++;
11261         _ASSERTE(pThread->m_cInsideRS == 1 || !"Non-reentrant API being called re-entrantly");
11262
11263         // Should never be in public w/ these locks
11264         pThread->AssertThreadIsLockFree();
11265     }
11266     ~PublicAPIHolder() {
11267         // On exit.
11268         DbgRSThread * pThread = DbgRSThread::GetThread();
11269         pThread->m_cInsideRS--;
11270         _ASSERTE(!pThread->IsInRS());
11271
11272         // Should never be in public w/ these locks. If we assert here,
11273         // then we're leaking locks.
11274         pThread->AssertThreadIsLockFree();
11275     }
11276 };
11277
11278 // Holder for reentrant public API
11279 class PublicReentrantAPIHolder
11280 {
11281 public:
11282     PublicReentrantAPIHolder()
11283     {
11284         // on entry
11285         DbgRSThread * pThread = DbgRSThread::GetThread();
11286         pThread->m_cInsideRS++;
11287
11288         // Cache count now so that we can calidate it in the dtor.
11289         m_oldCount = pThread->m_cInsideRS;
11290         // Since a we may have been called from within the RS, we may hold locks
11291     }
11292     ~PublicReentrantAPIHolder()
11293     {
11294
11295         // On exit.
11296         DbgRSThread * pThread = DbgRSThread::GetThread();
11297
11298         // Ensure that our children were balanced
11299         _ASSERTE(pThread->m_cInsideRS == m_oldCount);
11300
11301         pThread->m_cInsideRS--;
11302         _ASSERTE(pThread->m_cInsideRS >= 0);
11303
11304         // Since a we may have been called from within the RS, we may hold locks
11305     }
11306 private:
11307     int  m_oldCount;
11308 };
11309
11310 // Special holder for DebuggerError callback. This adjusts InsideRS count w/o
11311 // verifying locks. This is very dangerous. We allow this b/c the Debugger Error callback can come at any time.
11312 class PublicDebuggerErrorCallbackHolder
11313 {
11314 public:
11315     PublicDebuggerErrorCallbackHolder()
11316     {
11317         // Exiting from RS; entering Cordbg via a callback
11318         DbgRSThread * pThread = DbgRSThread::GetThread();
11319
11320         // This callback is called from within the RS
11321         _ASSERTE(pThread->IsInRS());
11322
11323         // Debugger error callback may be called from deep within the RS (after many nestings).
11324         // So immediately jump to outside. We'll restore this in dtor.
11325         m_oldCount = pThread->m_cInsideRS;
11326         pThread->m_cInsideRS = 0;
11327
11328         _ASSERTE(!pThread->IsInRS());
11329
11330         // We may be leaking locks for the unrecoverable callback. We mark that so that
11331         // the asserts about locking can be relaxed.
11332         pThread->SetUnrecoverableCallback(true);
11333     }
11334
11335     ~PublicDebuggerErrorCallbackHolder()
11336     {
11337         // Re-entering RS from after a callback.
11338         DbgRSThread * pThread = DbgRSThread::GetThread();
11339
11340         pThread->SetUnrecoverableCallback(false);
11341         pThread->m_cInsideRS = m_oldCount;
11342
11343         // Our status of being "Inside the RS" is now restored.
11344         _ASSERTE(pThread->IsInRS());
11345     }
11346 private:
11347     int m_oldCount;
11348 };
11349
11350 //---------------------------------------------------------------------------------------
11351 //
11352 // This is the same as the PublicCallbackHolder, except that this class doesn't assert that we are not holding
11353 // any locks when we call out to the shim.  
11354 // 
11355 // Notes:
11356 //    @dbgtodo  shim, synchronization - We need to settle on one consistent relationshipo between the RS
11357 //    and the shim.  Then we can clean up the sychronization story.  Right now some code considers the shim
11358 //    to be outside of the RS, and so we cannot hold any locks when we call out to the shim.  However, there
11359 //    are cases where we must hold a lock when we call out to the shim.  For example, when we call out to the
11360 //    shim to do a V2-style stackwalk, we need to be holding the stop-go lock so that another thread can't
11361 //    come in and call Continue().  Finally, when we fix this, we should fix 
11362 //    PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM() as well.
11363 //
11364
11365 class PrivateShimCallbackHolder 
11366 {
11367 public:
11368     PrivateShimCallbackHolder()
11369     {
11370         // Exiting from RS; entering Cordbg via a callback
11371         DbgRSThread * pThread = DbgRSThread::GetThread();
11372
11373         // This callback is called from within the RS
11374         _ASSERTE(pThread->IsInRS());
11375
11376         // Debugger error callback may be called from deep within the RS (after many nestings).
11377         // So immediately jump to outside. We'll restore this in dtor.
11378         m_oldCount = pThread->m_cInsideRS;
11379         pThread->m_cInsideRS = 0;
11380
11381         _ASSERTE(!pThread->IsInRS());
11382     }
11383
11384     ~PrivateShimCallbackHolder()
11385     {
11386         // Re-entering RS from after a callback.
11387         DbgRSThread * pThread = DbgRSThread::GetThread();
11388
11389         pThread->m_cInsideRS = m_oldCount;
11390
11391         // Our status of being "Inside the RS" is now restored.
11392         _ASSERTE(pThread->IsInRS());
11393     }
11394 private:
11395     int m_oldCount;
11396 };
11397
11398 class InternalAPIHolder
11399 {
11400 public:
11401     InternalAPIHolder()
11402     {
11403         DbgRSThread * pThread = DbgRSThread::GetThread();
11404
11405         // Internal APIs should already be inside the RS.
11406         _ASSERTE(pThread->IsInRS() ||!"Internal API being called directly from outside (there should be a public API on the stack)");
11407     }
11408     void dummy() {}
11409 };
11410
11411 //---------------------------------------------------------------------------------------
11412 //
11413 // This is a simple holder to assert that the current thread is holding the process lock.  The purpose of 
11414 // having this holder is to enforce a lock ordering between the process lock in the RS and the DD lock in DAC.
11415 // If a thread needs to take the process lock, it must do so BEFORE taking the DD lock.  Otherwise we could have
11416 // a deadlock between the process lock and the DD lock.
11417 //
11418 // Normally we take the process lock before calling out to DAC, and every DAC API takes the DD lock on entry.
11419 // Moreover, normally DAC doesn't call back into the RS.  The exceptions we currently have are:
11420 // 1) enumeration callbacks (e.g. code:CordbProcess::AppDomainEnumerationCallback)
11421 // 2) code:IDacDbiInterface::IMetaDataLookup
11422 // 3) code:IDacDbiInterface::IAllocator
11423 // 4) code:IStringHolder
11424 //
11425 // Note that the last two are fine because they don't need to take the process lock.  The first two categories
11426 // need to take the process lock before calling into DAC to avoid potential deadlocks.
11427 //
11428
11429 class InternalDacCallbackHolder
11430 {
11431 public:
11432     InternalDacCallbackHolder(CordbProcess * pProcess)
11433     {
11434         _ASSERTE(pProcess->ThreadHoldsProcessLock());
11435     }
11436 };
11437
11438 // cotract that occurs at public builds.
11439 #define PUBLIC_CONTRACT \
11440     CONTRACTL { NOTHROW; } CONTRACTL_END;
11441
11442
11443 // Private hook for Shim to call into DBI.
11444 // Since Shim is considered outside DBI, we need to mark that we've re-entered.
11445 // Big difference is that we can throw across this boundary.
11446 // @dbgtodo  private shim hook - Eventually, these will all go away since the shim will be fully public.
11447 #define PUBLIC_API_ENTRY_FOR_SHIM(_pThis) \
11448     PublicAPIHolder __pah;
11449
11450
11451 #define PUBLIC_API_UNSAFE_ENTRY_FOR_SHIM(_pThis) \
11452     PublicDebuggerErrorCallbackHolder __pahCallback;
11453
11454 // @dbgtodo  shim, synchronization - Because of the problem mentioned in the comments for 
11455 // PrivateShimCallbackHolder, we need this macro so that we don't hit an assertion when we come back into
11456 // the RS from the shim.
11457 #define PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM(_pThis) \
11458     PublicReentrantAPIHolder __pah;
11459
11460 //-----------------------------------------------------------------------------
11461 // Declare whether an API is public or internal
11462 // Public APIs have the following:
11463 // - We may be called concurrently from multiple threads (ie, not thread safe)
11464 // - This thread does not hold any RS Locks while entering or leaving this function.
11465 // - May or May-not be reentrant.
11466 // Internal APIs:
11467 // - let us specifically mark that we're not a public API, and
11468 // - we're only being called through a public API.
11469 //-----------------------------------------------------------------------------
11470 #define PUBLIC_API_ENTRY(_pThis) \
11471     STRESS_LOG2(LF_CORDB, LL_INFO1000, "[Public API '%s', this=0x%p]\n", __FUNCTION__, _pThis); \
11472     PUBLIC_CONTRACT; \
11473     PublicAPIHolder __pah;
11474
11475 // Mark public APIs that are re-entrant.
11476 // Very few of our APIs should be re-entrant. Even for field access APIs (like GetXXX), the
11477 // public version is heavier (eg, checking the HRESULT) so we benefit from having a fast
11478 // internal version and calling that directly.
11479 #define PUBLIC_REENTRANT_API_ENTRY(_pThis) \
11480     STRESS_LOG2(LF_CORDB, LL_INFO1000, "[Public API (re) '%s', this=0x%p]\n", __FUNCTION__, _pThis); \
11481     PUBLIC_CONTRACT; \
11482     PublicReentrantAPIHolder __pah;
11483
11484
11485
11486 // Mark internal APIs.
11487 // All internal APIs are reentrant (duh)
11488 #define INTERNAL_API_ENTRY(_pThis) InternalAPIHolder __pah; __pah.dummy();
11489
11490 // Mark an internal API from ATT_REQUIRE_STOP / ATT_ALLOW_LIVE_DO_STOP_GO.
11491 // This can assert that we're safe to send IPC events (that we're stopped and hold the SG lock)
11492 // @dbgtodo  synchronization - in V2, this would assert that we were synced. 
11493 // In V3, our definition of Sync is in flux.  Need to resolve this with the synchronization feature crew.
11494 #define INTERNAL_SYNC_API_ENTRY(pProc)  \
11495     CordbProcess * __pProc = (pProc); \
11496     _ASSERTE(__pProc->GetStopGoLock()->HasLock() || !"Must have stop go lock for internal-sync-api"); \
11497     InternalAPIHolder __pah; __pah.dummy();
11498
11499
11500
11501 // Mark that a thread is owned by us. Thus the thread's "Inside RS" count > 0.
11502 #define INTERNAL_THREAD_ENTRY(_pThis) \
11503     STRESS_LOG1(LF_CORDB, LL_INFO1000, "[Internal thread started, this=0x%p]\n", _pThis); \
11504     PUBLIC_CONTRACT; \
11505     PublicAPIHolder __pah;
11506
11507 // @dbgtodo  unrecoverable error - This sould be deprecated once we deprecate UnrecoverableError.
11508 #define PUBLIC_CALLBACK_IN_THIS_SCOPE_DEBUGGERERROR(_pThis) \
11509     PublicDebuggerErrorCallbackHolder __pahCallback;
11510
11511 #define PRIVATE_SHIM_CALLBACK_IN_THIS_SCOPE0(_pThis) \
11512     PrivateShimCallbackHolder __pahCallback;
11513
11514 // Mark places where DAC may call back into DBI.  We need to assert that we are holding the process lock in
11515 // these places, since otherwise we could deadlock between the DD lock and the process lock.
11516 #define INTERNAL_DAC_CALLBACK(__pProcess) \
11517     InternalDacCallbackHolder __idch(__pProcess);
11518
11519
11520 // Helper to log debug events.
11521 inline void StressLogNativeDebugEvent(const DEBUG_EVENT * pDebugEvent, bool fOOB)
11522 {
11523     if ((pDebugEvent)->dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
11524     {
11525         STRESS_LOG4(LF_CORDB, LL_EVERYTHING, "[Dispatching Win32 code=1 (EXCEPTION_DEBUG_EVENT, tid=%x, oob=%d, code=0x%x, 1st=%d]\n",
11526             pDebugEvent->dwThreadId,
11527             fOOB,
11528             pDebugEvent->u.Exception.ExceptionRecord.ExceptionCode,
11529             pDebugEvent->u.Exception.dwFirstChance);
11530     }
11531     else
11532     {
11533         STRESS_LOG3(LF_CORDB, LL_EVERYTHING, "[Dispatching Win32 code=%d, tid=%x, oob=%d.]\n",
11534             pDebugEvent->dwDebugEventCode, pDebugEvent->dwThreadId, fOOB);
11535     }
11536
11537 }
11538
11539 #define PUBLIC_WIN32_CALLBACK_IN_THIS_SCOPE(_pThis, _pDebugEvent, _fOOB) \
11540     StressLogNativeDebugEvent(_pDebugEvent, _fOOB); \
11541     PublicCallbackHolder __pahCallback(DB_IPCE_INVALID_EVENT);
11542
11543 // Visisbility spec for dtors.
11544 // Currently, dtors are like public methods b/c they can be called from Release.
11545 // But they're also reentrant since they may be called from an internal-release.
11546 // @todo - we'd like to get all "useful" work out of the dtor; in which case we may
11547 // be able to change this to something more aggressive.
11548 #define DTOR_ENTRY(_pThis) PUBLIC_REENTRANT_API_ENTRY(_pThis)
11549
11550
11551 //-----------------------------------------------------------------------------
11552 // Typesafe bool for thread safety. This typesafety forces us to use
11553 // an specific reason for thread-safety, taken from a well-known list.
11554 // This is mostly concerned w/ being serialized.
11555 // Note that this assertion must be done on a per function basis and we
11556 // can't have any sort of 'ThreadSafetyReason CallerIsSafe()' b/c we can't
11557 // enforce that all of our callers are thread safe (only that our current caller is safe).
11558 //-----------------------------------------------------------------------------
11559 struct ThreadSafetyReason
11560 {
11561 public:
11562     ThreadSafetyReason(bool f) { fIsSafe = f; }
11563
11564     bool fIsSafe;
11565 };
11566
11567 // Different valid reasons that we may be threads safe.
11568 inline ThreadSafetyReason HoldsLock(RSLock * pLock)
11569 {
11570     _ASSERTE(pLock != NULL);
11571     return ThreadSafetyReason(pLock->HasLock());
11572 }
11573 inline ThreadSafetyReason OnW32ET(CordbProcess * pProc)
11574 {
11575     return ThreadSafetyReason(IsWin32EventThread(pProc));
11576 }
11577
11578 inline ThreadSafetyReason OnRCET(Cordb *pCordb)
11579 {
11580     return ThreadSafetyReason (IsRCEventThread(pCordb));
11581 }
11582
11583 // We use this when we assume that a function is thread-safe (b/c it's serialized).
11584 // The reason also lets us assert that our assumption is true.
11585 // By using a function, we enforce typesafety and thus require a valid reason
11586 // (as opposed to an arbitrary bool)
11587 inline void AssertThreadSafeHelper(ThreadSafetyReason r) {
11588     _ASSERTE(r.fIsSafe);
11589 }
11590
11591 //-----------------------------------------------------------------------------
11592 // Assert that the given scope is always called on a single thread b/c of
11593 // xReason. Common reasons may be b/c we hold a lock or we're always
11594 // called on a specific thread (Eg w32et).
11595 // The only valid reasons are of type ThreadSafetyReason (thus forcing us to
11596 // choose from a well-known list of valid reasons).
11597 //-----------------------------------------------------------------------------
11598 #define ASSERT_SINGLE_THREAD_ONLY(xReason) \
11599     AssertThreadSafeHelper(xReason);
11600
11601 #else
11602
11603 //-----------------------------------------------------------------------------
11604 // Retail versions just nop. See the debug implementation for these
11605 // for their semantics.
11606 //-----------------------------------------------------------------------------
11607
11608 #define PUBLIC_CONTRACT
11609 #define PUBLIC_API_ENTRY_FOR_SHIM(_pThis)
11610 #define PUBLIC_API_UNSAFE_ENTRY_FOR_SHIM(_pThis)
11611 #define PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM(_pThis)
11612 #define PUBLIC_API_ENTRY(_pThis)
11613 #define PUBLIC_REENTRANT_API_ENTRY(_pThis)
11614 #define INTERNAL_API_ENTRY(_pThis)
11615 #define INTERNAL_SYNC_API_ENTRY(pProc)
11616 #define INTERNAL_THREAD_ENTRY(_pThis)
11617 #define PUBLIC_CALLBACK_IN_THIS_SCOPE_DEBUGGERERROR(_pThis)
11618 #define PRIVATE_SHIM_CALLBACK_IN_THIS_SCOPE0(_pThis)
11619 #define INTERNAL_DAC_CALLBACK(__pProcess)
11620 #define PUBLIC_WIN32_CALLBACK_IN_THIS_SCOPE(_pThis, _pDebugEvent, _fOOB)
11621 #define DTOR_ENTRY(_pThis)
11622
11623
11624 #define ASSERT_SINGLE_THREAD_ONLY(x)
11625
11626 #endif // #if RSCONTRACTS
11627
11628
11629 class PublicCallbackHolder
11630 {
11631 public:
11632     PublicCallbackHolder(RSLockHolder * pHolder, DebuggerIPCEventType type)        
11633     {
11634         m_pHolder = pHolder;
11635         _ASSERTE(!pHolder->IsNull()); // acquired
11636
11637         // Release the lock. We'll reacquire it at the dtor.
11638         m_pHolder->Release();
11639
11640         Init(type);
11641     }
11642
11643     PublicCallbackHolder(DebuggerIPCEventType type)
11644     {
11645         m_pHolder = NULL;
11646         Init(type);
11647     }
11648
11649     void Init(DebuggerIPCEventType type)
11650     {
11651         m_type = type;
11652
11653 #if defined(RSCONTRACTS)
11654         // Exiting from RS; entering Cordbg via a callback
11655         DbgRSThread * pThread = DbgRSThread::GetThread();
11656         
11657         // m_cInsideRS may be arbitrarily large if we're called from a PUBLIC_REENTRANT_API, 
11658         // so just remember the current count and blast it back to 0.
11659         m_oldCount = pThread->m_cInsideRS;
11660         pThread->m_cInsideRS = 0;
11661
11662         _ASSERTE(!pThread->IsInRS());
11663
11664         // Should never be in public w/ these locks. (Even if we're re-entrant.)
11665         pThread->AssertThreadIsLockFree();
11666 #endif // RSCONTRACTS
11667     }
11668
11669     ~PublicCallbackHolder()
11670     {
11671 #if defined(RSCONTRACTS)
11672         // Re-entering RS from after a callback.
11673         DbgRSThread * pThread = DbgRSThread::GetThread();
11674         _ASSERTE(!pThread->IsInRS());
11675         
11676         pThread->m_cInsideRS = m_oldCount;
11677
11678         // Should never be in public w/ these locks. (Even if we're re-entrant.)
11679         pThread->AssertThreadIsLockFree();
11680 #endif // RSCONTRACTS
11681
11682         // Reacquire the lock
11683         if (m_pHolder != NULL)
11684         {
11685             m_pHolder->Acquire();
11686         }
11687     }
11688 protected:
11689     int m_oldCount;
11690     DebuggerIPCEventType m_type;
11691     RSLockHolder * m_pHolder;
11692 };
11693
11694
11695 // Mark that a thread is calling out via a callback. This will adjust the "Inside RS" counter.
11696 #define PUBLIC_CALLBACK_IN_THIS_SCOPE(_pThis, pLockHolder, event) \
11697     STRESS_LOG1(LF_CORDB, LL_EVERYTHING, "[Dispatching '%s']\n", IPCENames::GetName((event)->type)); \
11698     PublicCallbackHolder __pahCallback(pLockHolder, (event)->type);
11699
11700 #define PUBLIC_CALLBACK_IN_THIS_SCOPE1(_pThis, pLockHolder, event, formatLiteralString, arg0) \
11701     STRESS_LOG2(LF_CORDB, LL_EVERYTHING, "[Dispatching '%s' " formatLiteralString "]\n", IPCENames::GetName((event)->type), arg0); \
11702     PublicCallbackHolder __pahCallback(pLockHolder, (event)->type);
11703
11704 #define PUBLIC_CALLBACK_IN_THIS_SCOPE2(_pThis, pLockHolder, event, formatLiteralString, arg0, arg1) \
11705     STRESS_LOG3(LF_CORDB, LL_EVERYTHING, "[Dispatching '%s' " formatLiteralString "]\n", IPCENames::GetName((event)->type), arg0, arg1); \
11706     PublicCallbackHolder __pahCallback(pLockHolder, (event)->type);
11707
11708 #define PUBLIC_CALLBACK_IN_THIS_SCOPE3(_pThis, pLockHolder, event, formatLiteralString, arg0, arg1, arg2) \
11709     STRESS_LOG4(LF_CORDB, LL_EVERYTHING, "[Dispatching '%s' " formatLiteralString "]\n", IPCENames::GetName((event)->type), arg0, arg1, arg2); \
11710     PublicCallbackHolder __pahCallback(pLockHolder, (event)->type);
11711
11712
11713 #define PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(_pThis) \
11714     PublicCallbackHolder __pahCallback(DB_IPCE_INVALID_EVENT);
11715
11716 #define PUBLIC_CALLBACK_IN_THIS_SCOPE0(_pThis, pLockHolder) \
11717     PublicCallbackHolder __pahCallback(pLockHolder, DB_IPCE_INVALID_EVENT);
11718
11719
11720 //-----------------------------------------------------------------------------
11721 // Helpers 
11722 inline void ValidateOrThrow(const void * p)
11723 {
11724     if (p == NULL)
11725     {
11726         ThrowHR(E_INVALIDARG);
11727     }
11728 }
11729
11730 // aligns argBase on platforms that require it else it's a no-op
11731 inline void AlignAddressForType(CordbType* pArgType, CORDB_ADDRESS& argBase)
11732 {
11733 #ifdef DBG_TARGET_ARM
11734 // TODO: review the following
11735 #ifdef FEATURE_64BIT_ALIGNMENT
11736     BOOL align = FALSE;
11737     HRESULT hr = pArgType->RequiresAlign8(&align);
11738     _ASSERTE(SUCCEEDED(hr));
11739
11740     if (align)
11741         argBase = ALIGN_ADDRESS(argBase, 8);
11742 #endif // FEATURE_64BIT_ALIGNMENT
11743 #endif // DBG_TARGET_ARM
11744 }
11745
11746 //-----------------------------------------------------------------------------
11747 // Macros to mark public ICorDebug functions
11748 // Usage:
11749 //
11750 //  HRESULT CordbXYZ:Function(...) 
11751 //  {
11752 //      HRESULT hr = S_OK;
11753 //      PUBLIC_API_BEGIN(this);
11754 //         // body, may throw
11755 //      PUBLIC_API_END(hr);
11756 //      return hr;
11757 //  }
11758 #define PUBLIC_API_BEGIN(__this) \
11759     CordbBase * __pThis = (__this); \
11760     PUBLIC_API_ENTRY(__pThis); \
11761     EX_TRY { \
11762        RSLockHolder __lockHolder(__pThis->GetProcess()->GetProcessLock()); \
11763        THROW_IF_NEUTERED(__pThis); \
11764
11765 // You should not use this in general. We're adding it as a temporary workaround for a 
11766 // particular scenario until we do the synchronization feature crew
11767 #define PUBLIC_API_NO_LOCK_BEGIN(__this) \
11768     CordbBase * __pThis = (__this); \
11769     PUBLIC_API_ENTRY(__pThis); \
11770     EX_TRY { \
11771        THROW_IF_NEUTERED(__pThis); \
11772
11773 // Some APIs (that invoke callbacks), need to toggle the lock.
11774 #define GET_PUBLIC_LOCK_HOLDER() (&__lockHolder)
11775
11776 #define PUBLIC_API_END(__hr) \
11777     } EX_CATCH_HRESULT(__hr); \
11778
11779 // @todo: clean up API constracts. Should we really be taking the Process lock for 
11780 // reentrant APIS?? 
11781 #define PUBLIC_REENTRANT_API_BEGIN(__this) \
11782     CordbBase * __pThis = (__this); \
11783     PUBLIC_REENTRANT_API_ENTRY(__pThis); \
11784     EX_TRY { \
11785        RSLockHolder __lockHolder(__pThis->GetProcess()->GetProcessLock()); \
11786        THROW_IF_NEUTERED(__pThis); \
11787
11788 #define PUBLIC_REENTRANT_API_END(__hr) \
11789     } EX_CATCH_HRESULT(__hr); \
11790
11791 // If an API needs to take the stop/go lock as well as the process lock, the
11792 // stop/go lock has to be taken first. This is an alternative to PUBLIC_REENTRANT_API_BEGIN
11793 // that allows this, since it doesn't take the process lock. It should be closed with 
11794 // PUBLIC_REENTRANT_API_END
11795 #define PUBLIC_REENTRANT_API_NO_LOCK_BEGIN(__this) \
11796     CordbBase * __pThis = (__this); \
11797     PUBLIC_REENTRANT_API_ENTRY(__pThis); \
11798     EX_TRY { \
11799        THROW_IF_NEUTERED(__pThis); \
11800
11801
11802 //-----------------------------------------------------------------------------
11803 // For debugging ease, cache some global values.
11804 // Include these in retail & free because that's where we need them the most!!
11805 // Optimized builds may not let us view locals & parameters. So Having these
11806 // cached as global values should let us inspect almost all of
11807 // the interesting parts of the RS even in a Retail build!
11808 //-----------------------------------------------------------------------------
11809 struct RSDebuggingInfo
11810 {
11811     // There should only be 1 global Cordb object. Store it here.
11812     Cordb * m_Cordb;
11813
11814     // We have lots of processes. Keep a pointer to the most recently touched
11815     // (subjective) process, as a hint about what our "current" process is.
11816     // If we're only debugging 1 process, this will be sufficient.
11817     CordbProcess * m_MRUprocess;
11818
11819     CordbRCEventThread * m_RCET;
11820 };
11821
11822 #include "rspriv.inl"
11823
11824 #endif // #if RSPRIV_H
11825
11826