Pipe based communication between debugee and managed debugger on Linux
[platform/upstream/coreclr.git] / src / debug / di / rspriv.h
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
4 //
5 //*****************************************************************************
6 // rspriv.
7 // 
8
9 //
10 // Common include file for right-side of debugger.
11 //*****************************************************************************
12
13 #ifndef RSPRIV_H
14 #define RSPRIV_H
15
16 #include <winwrap.h>
17 #include <windows.h>
18
19 #include <utilcode.h>
20
21
22 #ifdef _DEBUG
23 #define LOGGING
24 #endif
25
26 #include <log.h>
27 #include <corerror.h>
28
29 #include "cor.h"
30
31 #include "cordebug.h"
32 #include "xcordebug.h"
33 #include "cordbpriv.h"
34 #include "mscoree.h"
35
36 #include <cordbpriv.h>
37 #include <dbgipcevents.h>
38
39 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
40 #include <ipcmanagerinterface.h>
41 #endif // !FEATURE_DBGIPC_TRANSPORT_DI
42
43 #include "common.h"
44 #include "primitives.h"
45
46 #include "dacdbiinterface.h"
47
48 #include "helpers.h"
49
50 struct MachineInfo;
51
52 #include "nativepipeline.h"
53 #include "stringcopyholder.h"
54
55
56 #include "eventchannel.h"
57
58 #undef ASSERT
59 #define CRASH(x)  _ASSERTE(!x)
60 #define ASSERT(x) _ASSERTE(x)
61
62 // We want to keep the 'worst' HRESULT - if one has failed (..._E_...) & the
63 // other hasn't, take the failing one.  If they've both/neither failed, then
64 // it doesn't matter which we take.
65 // Note that this macro favors retaining the first argument
66 #define WORST_HR(hr1,hr2) (FAILED(hr1)?hr1:hr2)
67
68 // #UseDataTarget
69 // Forbid usage of OS APIs that we should be using the data-target for
70 #define ReadProcessMemory DONT_USE_READPROCESS_MEMORY
71 #define WriteProcessMemory DONT_USE_WRITEPROCESS_MEMORY
72
73
74 /* ------------------------------------------------------------------------- *
75  * Forward class declarations
76  * ------------------------------------------------------------------------- */
77
78 class CordbBase;
79 class CordbValue;
80 class CordbModule;
81 class CordbClass;
82 class CordbFunction;
83 class CordbCode;
84 class CordbFrame;
85 class CordbJITILFrame;
86 class CordbInternalFrame;
87 class CordbContext;
88 class CordbThread;
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 extern HINSTANCE GetModuleInst();
142
143
144 template <class T>
145 class CordbSafeHashTable;
146
147
148 //---------------------------------------------------------------------------------------
149 //
150 // This is an encapsulation of the information necessary to connect to the debugger proxy on a remote machine. 
151 // It includes the IP address and the port number.  The IP address can be set via the env var 
152 // COMPlus_DbgTransportProxyAddress, and the port number is fixed when Mac debugging is configured.
153 //    
154
155 struct MachineInfo
156 {
157 public:
158     void Init(DWORD dwIPAddress, USHORT usPort)
159     {
160         m_dwIPAddress = dwIPAddress;
161         m_usPort      = usPort;
162     }
163
164     void Clear()
165     {
166         m_dwIPAddress = 0;
167         m_usPort      = 0;
168     }
169
170     DWORD  GetIPAddress() {return m_dwIPAddress;};
171     USHORT GetPort() {return m_usPort;};
172
173 private:
174     DWORD  m_dwIPAddress;
175     USHORT m_usPort;
176 };
177
178 #define forDbi (*(forDbiWorker *)NULL)
179
180 // for dbi we just default to new, but we need to have these defined for both dac and dbi
181 inline void * operator new(size_t lenBytes, const forDbiWorker &)
182 {
183     void * result = new BYTE[lenBytes];
184     if (result == NULL) 
185     {
186         ThrowOutOfMemory();
187     }
188     return result;
189 }
190
191 inline void * operator new[](size_t lenBytes, const forDbiWorker &)
192 {
193     void * result = new BYTE[lenBytes];
194     if (result == NULL) 
195     {
196         ThrowOutOfMemory();
197     }
198     return result;
199 }
200
201 // Helper to delete memory used with the IDacDbiInterface::IAllocator  interface.
202 template<class T> inline
203 void DeleteDbiMemory(T *p)
204 {
205     delete p;
206 }
207
208
209
210 //---------------------------------------------------------------------------------------
211 //
212 // Simple array of holders (either RSSmartPtrs or RSExtSmartPtrs).
213 // Holds a reference to each element.
214 //
215 // Notes:
216 //    T is the base type and HOLDER_T is the type of the holder.  All functions implemented on this base
217 //    class must work for both RSSmartPtrs and RSExtSmartPtrs.  For example, there is no concept of neutering
218 //    for RSExtSmartPtrs.
219 //
220
221 template<typename T, typename HOLDER_T>
222 class BaseRSPtrArray
223 {
224 public:
225     BaseRSPtrArray()
226     {
227         m_pArray = NULL;
228         m_cElements = 0;
229     }
230
231     // Is the array emtpy? 
232     bool IsEmpty() const
233     {
234         return (m_pArray == NULL);
235     }
236
237     // Allocate an array of ptrs.
238     // Returns false if not enough memory; else true.
239     bool Alloc(unsigned int cElements)
240     {
241         // Caller should have already Neutered
242         _ASSERTE(IsEmpty());
243
244         // It's legal to allocate 0 items. We'll succeed the allocation, but still claim that IsEmpty() == true.
245         if (cElements == 0)
246         {
247             return true;
248         }
249
250         // RSSmartPtr ctor will ensure all elements are null initialized.
251         m_pArray = new (nothrow) HOLDER_T [cElements];
252         if (m_pArray == NULL)
253         {
254             return false;
255         }
256
257         m_cElements = cElements;
258         return true;
259     }
260
261     // Allocate an array of ptrs.
262     // Throw on failure
263     void AllocOrThrow(unsigned int cElements)
264     {
265         if (!Alloc(cElements))
266         {
267             ThrowOutOfMemory();
268         }
269     }
270
271     // Release each element and empty the array.
272     void Clear()
273     {
274         // this Invoke dtors on each element which will release each element
275         delete [] m_pArray;
276
277         m_pArray = NULL;
278         m_cElements = 0;
279     }
280
281     // Array lookup. Caller gaurantees this is in range.
282     // Used for reading
283     T* operator [] (unsigned int index) const
284     {
285         _ASSERTE(m_pArray != NULL);
286         CONSISTENCY_CHECK_MSGF((index <= m_cElements), ("Index out of range. Index=%u, Max=%u\n", index, m_cElements));
287         
288         return m_pArray[index];
289     }
290
291     // Assign a given index to the given value. The array holder will increment the internal reference on the value.
292     void Assign(unsigned int index, T* pValue)
293     {
294         _ASSERTE(m_pArray != NULL);
295         CONSISTENCY_CHECK_MSGF((index <= m_cElements), ("Index out of range. Index=%u, Max=%u\n", index, m_cElements));
296         
297         m_pArray[index].Assign(pValue);
298     }
299
300     // Get lenght of array in elements.
301     unsigned int Length() const
302     {
303         return m_cElements;
304     }
305
306     // Some things need to get the address of an element in the table.
307     // For example, CordbThreads have an array of CordbFrame objects, and then CordbChains describe a range
308     // or frames via pointers into the CordbThread's array.
309     // This is a dangerous operation because it lets us side-step reference counting and protection.
310     T ** UnsafeGetAddrOfIndex(unsigned int index)
311     {
312         return m_pArray[index].UnsafeGetAddr();
313     }
314
315 protected:
316     // Raw array of values. 
317     HOLDER_T * m_pArray;
318
319     // Number of elements in m_pArray. Note the following is always true: (m_cElements == 0) == (m_pArray == NULL);
320     unsigned int m_cElements; 
321 };
322
323
324 //-----------------------------------------------------------------------------
325 //
326 // Simple array holder of RSSmartPtrs (internal pointers).
327 // Holds a reference to each element.
328 //
329 // Notes:
330 //    This derived class adds the concept of neutering to the base pointer array.
331 //    Allows automatic Clear()ing; do not use this unless it is safe to do so in
332 //    all cases - e.g. you're holding a local.
333 //
334
335 template< typename T, typename HOLDER_T = RSSmartPtr<T> >   // We need to use HOLDER_T to make gcc happy.
336 class RSPtrArray : public BaseRSPtrArray<T, HOLDER_T>
337 {
338 private:
339     typedef BaseRSPtrArray<T, HOLDER_T> Super;
340     BOOL m_autoClear;
341
342 public:
343     RSPtrArray() : m_autoClear(FALSE)
344     {
345     }
346     
347     ~RSPtrArray()
348     {
349         if (m_autoClear)
350         {
351             Super::Clear();
352         }
353         else
354         {
355             // Caller should have already Neutered
356             _ASSERTE(Super::IsEmpty());
357         }
358     }
359
360     void EnableAutoClear()
361     {
362         m_autoClear = TRUE;
363     }
364
365     // Neuter all elements in the array.
366     void NeuterAndClear()
367     {
368         for(unsigned int i = 0; i < Super::m_cElements; i++)
369         {
370             if (Super::m_pArray[i] != NULL)
371             {
372                 Super::m_pArray[i]->Neuter();
373             }
374         }
375
376         Super::Clear();
377     }
378 };
379
380
381 //-----------------------------------------------------------------------------
382 //
383 // Simple array holder of RSExtSmartPtrs (external pointers).
384 // Holds a reference to each element.
385 //
386 // Notes:
387 //    This derived class clears the array in its destructor.
388 //
389
390 template< typename T, typename HOLDER_T = RSExtSmartPtr<T> >    // We need to use HOLDER_T to make gcc happy.
391 class RSExtPtrArray : public BaseRSPtrArray<T, HOLDER_T>
392 {
393 private:
394     typedef BaseRSPtrArray<T, HOLDER_T> Super;
395
396 public:
397     ~RSExtPtrArray()
398     {
399         Super::Clear();
400     }
401 };
402
403
404
405 //-----------------------------------------------------------------------------
406 // Table for RSptrs
407 // This lets us map cookies <--> RSPTR_*,
408 // Then we just put the cookie in the IPC block instead of the raw RSPTR.
409 // This will also adjust the internal-reference count on the T* object.
410 // This isolates the RS from bugs in the LS.
411 // We templatize by type for type safety.
412 // Caller must syncrhonize all access (preferably w/ the stop-go lock).
413 //-----------------------------------------------------------------------------
414 template <class T>
415 class RsPtrTable
416 {
417 public:
418     RsPtrTable()
419     {
420         m_pTable = NULL;
421         m_cEntries = 0;
422     }
423     ~RsPtrTable()
424     {        
425         Clear();
426     }
427     void Clear()
428     {
429         for(UINT i = 0; i < m_cEntries; i++)
430         {
431             if (m_pTable[i])
432             {
433                 m_pTable[i]->InternalRelease();
434             }
435         }
436         delete [] m_pTable;
437         m_pTable = NULL;
438         m_cEntries = 0;
439     }
440
441     // Add a value into table.  Value can't be NULL.
442     // Returns 0 on failure (such as oom),
443     // Returns a non-zero cookie on success.
444     UINT Add(T* pValue)
445     {
446         _ASSERTE(pValue != NULL);
447         // skip 0 because it's an invalid handle.
448         for(UINT i = 1; ; i++)
449         {
450             // If we've run out of space, allocate new space
451             if( i >= m_cEntries ) 
452             {
453                 if( !Grow() )
454                 {
455                     return 0;   // failed to grow
456                 }
457                 _ASSERTE( i < m_cEntries );
458                 _ASSERTE( m_pTable[i] == NULL );
459                 // Since we grew, the next slot should now be open.
460             }
461             
462             if (m_pTable[i] == NULL)
463             {
464                 m_pTable[i] = pValue;
465                 pValue->InternalAddRef();
466                 return i;
467             }
468         }
469         UNREACHABLE();      
470     }
471
472     // Lookup the value based off the cookie, which was obtained via "Add".
473     // return NULL on error. 
474     T* Lookup(UINT cookie)
475     {
476         _ASSERTE(cookie != 0);
477         if (cookie >= m_cEntries) 
478         {
479             CONSISTENCY_CHECK_MSGF(false, ("Cookie out of range.Cookie=0x%x. Size=0x%x.\n", cookie, m_cEntries));
480             return NULL;
481         }
482         T*  p = m_pTable[cookie];
483         if (p == NULL) 
484         {   
485             CONSISTENCY_CHECK_MSGF(false, ("Cookie is for empty slot.Cookie=0x%x.\n", cookie));
486             return NULL; // empty!
487         }
488         return p;
489     }
490
491     T* LookupAndRemove(UINT cookie)
492     {
493         _ASSERTE(cookie != 0);
494         T* p  = Lookup(cookie);
495         if (p != NULL)
496         {
497             m_pTable[cookie] = NULL;
498             p->InternalRelease();
499         }
500         return p;
501     }
502
503 protected:
504     // Resize the m_pTable array.
505     bool Grow()
506     {
507         if (m_pTable == NULL)
508         {
509             _ASSERTE(m_cEntries == 0);
510             size_t cSize = 10;
511             m_pTable = new (nothrow) T*[cSize];
512             if (m_pTable == NULL)
513             {
514                 return false;
515             }
516             m_cEntries = cSize;
517             ZeroMemory(m_pTable, sizeof(T*) * m_cEntries);
518             return true;
519         }
520         size_t cNewSize = (m_cEntries * 3 / 2) + 1;
521         _ASSERTE(cNewSize > m_cEntries);
522         T** p = new (nothrow) T*[cNewSize];
523         if (p == NULL) 
524         {
525             return false;
526         }
527         ZeroMemory(p, sizeof(T*) * cNewSize);        
528
529
530         // Copy over old stuff
531         memcpy(p, m_pTable, sizeof(T*) * m_cEntries);
532         delete [] m_pTable;        
533
534         m_pTable = p;
535         m_cEntries = cNewSize;
536         return true;        
537     }
538     
539     T** m_pTable;
540     size_t m_cEntries;    
541 };
542
543
544
545 //-----------------------------------------------------------------------------
546 // Simple Holder for RS object intialization to cooperate with Neutering 
547 // semantics. 
548 // The ctor will do an addref. 
549 // The dtor (invoked in exception) will neuter and release the object. This
550 // release will likely be the final release to cause a delete.
551 // If the object is created successfully, caller should do a SuppressRelease()
552 // to avoid it getting neutered.
553 //
554 // Example: 
555 //    RSInitHolder<CordbFoo> pFoo(new CordbFoo(x,y,z));
556 //    pFoo->InitMore(a,b,c);
557 //    GiveOwnershipToSomebodyElse(pFoo); // now somebody else owns and will clean up
558 //    pFoo.ClearAndMarkDontNeuter();  // we no longer need to
559 //    
560 // So if an exception is thrown before ClearAndMarkDontNeuter(), the dtor is invoked
561 // and the object is properly destroyed (deleted and neutered). 
562 //
563 // Another common pattern is when initializing an object to hand off to an external:
564 //    RSInitHolder<CordbFoo> pFoo(new CordbFoo(x,y,z));
565 //    pFoo->InitMore(a,b,c);
566 //    pFoo.TransferOwnershipExternal(ppOutParameter);  
567 // TransferOwnershipExternal will assign to ppOutParameter, inc external ref, and
568 //  call ClearAndMarkDontNeuter()
569 //-----------------------------------------------------------------------------
570 template<class T>
571 class RSInitHolder
572 {
573 public:
574     // Default ctor. Must call Assign() later.
575     RSInitHolder()
576     {
577     };
578     RSInitHolder(T * pObject)
579     {
580         Assign(pObject);
581     }
582
583     void Assign(T * pObject)
584     {
585         _ASSERTE(m_pObject == NULL); // only assign once.
586         m_pObject.Assign(pObject);
587     }
588     ~RSInitHolder();
589
590     FORCEINLINE operator T *() const
591     {
592         return m_pObject;
593     
594     }
595     FORCEINLINE T * operator->()
596     {
597         return m_pObject;
598     }
599
600     // This will null out m_pObject such that the dtor will not neuter it.
601     // This will also release the ref we took in the ctor.
602     // This will clear the current pointer.
603     void ClearAndMarkDontNeuter()
604     {
605         m_pObject.Clear();
606     }
607
608     //
609     // Transfer ownership to a pointer
610     //
611     // Arguments:
612     //     ppOutParam - pointer to get ownership. External Reference is incremented.
613     //                   this pointer should do an external release.
614     //
615     // Notes:
616     //    This calls ClearAndMarkDontNeuter(). This holder is Empty after this.
617     template <class TOther>
618     void TransferOwnershipExternal(TOther ** ppOutParam)
619     {
620         *ppOutParam = static_cast<TOther*> (m_pObject);
621         m_pObject->ExternalAddRef();
622
623         ClearAndMarkDontNeuter();
624     }
625     
626     
627     //
628     // Transfer the ownership of the wrapped object to the given hash table.    
629     //
630     // Arguments:
631     //    pHashTable - hash table to take ownership. 
632     //
633     // Returns:
634     //    the contianing object for convenience. Throws on error (particularly
635     //    if it fails adding to the hash).
636     //
637     // Notes:
638     //    This calls ClearAndMarkDontNeuter(). This holder is Empty after this.  
639     T* TransferOwnershipToHash(CordbSafeHashTable<T> * pHashtable)
640     {
641         T* pObject = m_pObject;
642         pHashtable->AddBaseOrThrow(m_pObject);
643         ClearAndMarkDontNeuter();
644         return pObject;
645     }
646
647     //
648     // Used to pass into a function that will assign to us.
649     //
650     // Returns:
651     //     Address of this holder. This is like the & operator. 
652     //     This is provided for consistency with other holders which 
653     //     override the &operator.
654     RSInitHolder<T> * GetAddr()
655     {
656         return this;
657     }
658
659
660 protected:
661     RSSmartPtr<T> m_pObject;
662 };
663
664
665
666 //-----------------------------------------------------------------------------
667 // Have the extra level of indirection is useful for catching Cordbg errors.
668 //-----------------------------------------------------------------------------
669 #ifdef _DEBUG
670     // On debug, we have an opportunity to catch failing hresults during reproes.
671     #define ErrWrapper(hr) ErrWrapperHelper(hr, __FILE__, __LINE__)
672
673     inline HRESULT ErrWrapperHelper(HRESULT hr, const char * szFile, int line)
674     {
675         if (FAILED(hr))
676         {
677             DWORD dwErr = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgBreakOnErr);
678             if (dwErr)
679             {
680                 CONSISTENCY_CHECK_MSGF(false, ("Dbg Error break, hr=0x%08x, '%s':%d", hr, szFile, line));
681             }
682         }
683         return hr;
684     }
685 #else
686     // On release, it's just an identity function
687     #define ErrWrapper(hr) (hr)
688 #endif
689
690 //-----------------------------------------------------------------------------
691 // Quick helpers for threading semantics
692 //-----------------------------------------------------------------------------
693
694 bool IsWin32EventThread(CordbProcess* p);
695 bool IsRCEventThread(Cordb* p);
696
697 /* ------------------------------------------------------------------------- *
698  * Typedefs
699  * ------------------------------------------------------------------------- */
700
701 typedef void* REMOTE_PTR;
702
703
704 //-----------------------------------------------------------------------------
705 // Wrapper class for locks. This is like Crst on the LS
706 //-----------------------------------------------------------------------------
707
708 class RSLock
709 {
710 public:
711     // Attrs, can be bitwise-or together.
712     enum ELockAttr
713     {
714         cLockUninit     = 0x00000000,
715         cLockReentrant  = 0x00000001,
716         cLockFlat       = 0x00000002,
717
718         // (unusual).  Not considered a debug API lock, for purposes of deciding whether
719         // to count this lock in m_cTotalDbgApiLocks, which is asserted to be 0 on entry
720         // to public APIs.  Example of such a lock: LL_SHIM_PROCESS_DISPOSE_LOCK
721         cLockNonDbgApi  = 0x00000004,
722     };
723
724     // To prevent deadlocks, we order all locks.
725     // A thread must acquire higher-numbered locks before lower numbered locks.
726     // These are used as indices into an array, so number them accordingly!
727     enum ERSLockLevel
728     {
729         // Size of the array..
730         LL_MAX = 6,
731
732         // The Stop-Go lock is used to make Stop + Continue be atomic operations.
733         // These methods will toggle the Process-lock b/c they go between multiple threads.
734         // This lock can never be taken on the Win32 ET.
735         LL_STOP_GO_LOCK = 5,
736
737         // The win32-event-thread behaves as if it held a lock at this level.
738         LL_WIN32_EVENT_THREAD = 4,
739
740         // This held for the duration of ShimProcess::Dispose(), and protects
741         // ShimProcess::m_fIsDisposed, so that other ShimProcess functions can
742         // safely execute serially with ShimProcess::Dispose().  This needs to be
743         // a high-level lock, since ShimProcess methods that take this lock also
744         // call into CorDb* objects which take many of the other locks.  In contrast,
745         // LL_SHIM_LOCK must remain low-level, as there exists at least one place where
746         // LL_SHIM_LOCK is taken while the CorDbProcess lock is also held (see
747         // CordbThread::GetActiveFunctions which takes the CorDbProcess lock while
748         // calling GetProcess()->GetShim()->LookupOrCreateShimStackWalk(this), which
749         // takes LL_SHIM_LOCK).
750         LL_SHIM_PROCESS_DISPOSE_LOCK = 3,
751
752         // The process lock is the primary lock for a CordbProcess object. It synchronizes
753         // between RCET, W32ET, and user threads.
754         LL_PROCESS_LOCK = 2,
755
756 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
757         LL_DBG_TRANSPORT_MANAGER_LOCK = 1,
758
759         LL_DBG_TRANSPORT_TARGET_LOCK = 0,
760
761         LL_DD_MARSHAL_LOCK = 0,
762 #endif // FEATURE_DBGIPC_TRANSPORT_DI
763
764         // These are all leaf locks (they don't take any other lock once they're held).
765         LL_PROCESS_LIST_LOCK = 0,
766
767         // Win32 send lock is shared by all processes accessing a single w32et.
768         LL_WIN32_SEND_LOCK = 0,
769
770         // Small lock around sending IPC events to support workarounds in func-eval abort.
771         // See code:CordbEval::Abort for details.
772         LL_FUNC_EVAL_ABORT_HACK_LOCK = 0,
773
774         // Leaf-level lock used in the shim.
775         LL_SHIM_LOCK = 0
776     };
777
778     // Initialize a lock w/ debugging info. szTag must be a string literal.
779     void Init(const char * szTag, int eAttr, ERSLockLevel level);
780     void Destroy();
781
782     void Lock();
783     void Unlock();
784
785 protected:
786     // Accessors for holders.
787     static void HolderEnter(RSLock * pLock)
788     {
789         pLock->Lock();
790     }
791     static void HolderLeave(RSLock * pLock)
792     {
793         pLock->Unlock();
794     }
795
796
797     CRITICAL_SECTION m_lock;
798
799 #ifdef _DEBUG
800 public:
801     RSLock();
802     ~RSLock();
803
804     const char * Name() { return m_szTag; }
805
806     // Returns true if this thread has the lock.
807     bool HasLock();
808
809     // Returns true if this is safe to take on this thread (ie, this thread
810     // doesn't already hold bigger locks).
811     // bool IsSafeToTake();
812
813     ERSLockLevel GetLevel() { return m_level; }
814
815     // If we're inited, we must have either  cLockReentrant or cLockFlat specified.
816     bool IsInit() { return m_eAttr != 0; }
817     bool IsReentrant() { return (m_eAttr & cLockReentrant) == cLockReentrant; }
818     bool IsDbgApiLock() { return ((m_eAttr & cLockNonDbgApi) == 0); }
819
820 protected:
821     ERSLockLevel m_level;
822     int m_eAttr;        // Bitwise combination of ELockAttr values
823     int m_count;
824     DWORD m_tidOwner;
825     const char * m_szTag;
826
827 #endif // #if debug
828
829 public:
830     typedef Holder<RSLock *, RSLock::HolderEnter, RSLock::HolderLeave> RSLockHolder;
831     typedef Holder<RSLock *, RSLock::HolderLeave, RSLock::HolderEnter> RSInverseLockHolder;
832
833 };
834
835 typedef RSLock::RSLockHolder RSLockHolder;
836 typedef RSLock::RSInverseLockHolder RSInverseLockHolder;
837
838 // In the RS, we should be using RSLocks instead of raw critical sections.
839 #define CRITICAL_SECTION USE_RSLOCK_INSTEAD_OF_CRITICAL_SECTION
840
841
842 /* ------------------------------------------------------------------------- *
843  * Helper macros. Use the ATT_* macros below instead of these.
844  * ------------------------------------------------------------------------- */
845
846 // This serves as glue for exceptions. Eventually, we shouldn't have unrecoverable
847 // error, and instead, errors should just propogate up.
848 #define SetUnrecoverableIfFailed(__p, __hr) \
849     if (FAILED(__hr)) \
850     { \
851        CORDBSetUnrecoverableError(__p, __hr, 0); \
852     } 
853
854 #define CORDBSetUnrecoverableError(__p, __hr, __code) \
855     ((__p)->UnrecoverableError((__hr), (__code), __FILE__, __LINE__))
856
857 #define _CORDBCheckProcessStateOK(__p) \
858     (!((__p)->m_unrecoverableError) && !((__p)->m_terminated) && !((__p)->m_detached))
859
860 #define _CORDBCheckProcessStateOKAndSync(__p, __c) \
861     (!((__p)->m_unrecoverableError) && !((__p)->m_terminated) && !((__p)->m_detached) && \
862     (__p)->GetSynchronized())
863
864 // Worker to get failure HR from given state. If not in a failure state, it yields __defaultHR.
865 // If a caller knows that we're in a failure state, it can pass in a failure value for __defaultHR.
866 #define CORDBHRFromProcessStateWorker(__p, __c, __defaultHR) \
867         ((__p)->m_unrecoverableError ? CORDBG_E_UNRECOVERABLE_ERROR : \
868          ((__p)->m_detached ? CORDBG_E_PROCESS_DETACHED : \
869          ((__p)->m_terminated ? CORDBG_E_PROCESS_TERMINATED : \
870          (!(__p)->GetSynchronized() ? CORDBG_E_PROCESS_NOT_SYNCHRONIZED \
871          : (__defaultHR)))))
872
873 #define CORDBHRFromProcessState(__p, __c) \
874     CORDBHRFromProcessStateWorker(__p, __c, S_OK) \
875
876
877 // Have a set of helper macros to check the process state and return a failure code.
878 // These only should be used at public interface boundaries, in which case we should
879 // not be holding the process lock. But we have enough places where we use them internally,
880 // so we can't really assert that we're not holding the lock.
881
882 // We're very restricted in what APIs we can call on the w32et. Have
883 // a convenient check for this.
884 // If we have no shim, then nop this check because everything becomes like the w32-event-thread.
885 #define CORDBFailOrThrowIfOnWin32EventThread(__p, errorAction) \
886     { \
887         if (((__p)->GetShim() != NULL) && (__p)->IsWin32EventThread()) \
888         { \
889             _ASSERTE(!"Don't call on this thread"); \
890             errorAction(ErrWrapper(CORDBG_E_CANT_CALL_ON_THIS_THREAD)); \
891         } \
892     }
893
894 #define CORDBFailIfOnWin32EventThread(__p) CORDBFailOrThrowIfOnWin32EventThread(__p, return)
895
896 #define CORDBRequireProcessStateOK(__p) { \
897     if (!_CORDBCheckProcessStateOK(__p)) \
898         return ErrWrapper(CORDBHRFromProcessState(__p, NULL)); }
899
900 // If we need to be synced, then we shouldn't be on the win32 Event-Thread.
901 #define CORDBRequireProcessStateOKAndSync(__p,__c) { \
902     CORDBFailIfOnWin32EventThread(__p); \
903     if (!_CORDBCheckProcessStateOKAndSync(__p, __c)) \
904         return ErrWrapper(CORDBHRFromProcessState(__p, __c)); }
905
906 #define CORDBRequireProcessSynchronized(__p, __c) { \
907     CORDBFailIfOnWin32EventThread(__p); \
908     if (!(__p)->GetSynchronized()) return ErrWrapper(CORDBG_E_PROCESS_NOT_SYNCHRONIZED);}
909
910
911        
912
913 //-----------------------------------------------------------------------------
914 // All public APIS fall into 2 categories regarding their API Threading Type (ATT)
915 // We use a standard set of macros to define & enforce each type.
916 //
917 // (1) ATT_REQUIRE_STOPPED
918 // We must be stopped (either synced or at a win32 event) to call this API.
919 // - We'll fail if we're not stopped.
920 // - If we're stopped, we'll sync. Thus after this API, we're always synced,
921 //   and Cordbg must call Continue to resume the process.
922 // - We'll take the Stop-Go-lock. This prevents another thread from continuing underneath us.
923 // - We may send IPC events.
924 // Common for APIs like Stacktracing
925 //
926 // (2) ATT_ALLOW_LIVE
927 // We do not have to be stopped to call this API.
928 // - We can be live, thus we can not take the stop-go lock (unless it's from a SC-holder).
929 // - If we're going to send IPC events, we must use a Stop-Continue holder.
930 // - Our stop-status is the same after this API as it was before.
931 // Common usage: read-only APIs.
932 //
933 // (2b) ATT_ALLOW_LIVE_DO_STOPGO.
934 // - shortcut macro to do #2, but throw in a stop-continue holder. These really
935 // should be in camp #1, but that would require an interface change.
936 //-----------------------------------------------------------------------------
937
938 // Helper macros for the ATT stuff
939
940 // Do checks that need to be done before we take the SG lock. These include checks
941 // where if we fail them, taking the SG lock could deadlock (such as being on win32 thread).
942 #define DO_PRE_STOP_GO_CHECKS(errorAction) \
943     CORDBFailOrThrowIfOnWin32EventThread(__proc_for_ATT, errorAction) \
944     if ((__proc_for_ATT)->m_unrecoverableError) { errorAction(CORDBG_E_UNRECOVERABLE_ERROR); } \
945
946 // Do checks after we take the SG lock. These include checks that rely on state protected
947 // by the SG lock.
948 #define DO_POST_STOP_GO_CHECKS(errorAction) \
949     _ASSERTE((this->GetProcess() == __proc_for_ATT) || this->IsNeutered()); \
950     if (this->IsNeutered()) { errorAction(CORDBG_E_OBJECT_NEUTERED); } \
951
952 // #1
953 // The exact details here are rocket-science.
954 // 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).
955 // This is essential in case __proc is something like "this->GetProcess()" and which can start returning NULL if 'this' 
956 // gets neutered underneath us. Caching guarantees that we'll be able to make it to the StopGo-lock. 
957 // 
958 // We explicitily check some things before taking the Stop-Go lock:
959 // - CORDBG_E_UNRECOVERABLE_ERROR before the lock because if that's set,
960 //   we may have leaked locks to the outside world, so taking the StopGo lock later could fail.
961 // - Are we on the W32et - can't take sg lock if on W32et
962 // Then we immediately take the stop-go lock to prevent another thread from continuing underneath us.
963 // Then, if we're stopped, we ensure that we're also synced.
964 // Stopped includes:
965 // - Win32-stopped
966 // - fake win32-stopped. Eg, between SuspendUnmanagedThreads & ResumeUnmanagedThreads
967 //   (one way to get here is getting debug events during the special-deferment region)
968 // - synchronized
969 // If we're not stopped, then we fail.  This macro must never return S_OK.
970 //
971 // If not-shimmed (using V3 pipeline), then skip all checks about stop-state.
972 #define ATT_REQUIRE_STOPPED_MAY_FAIL_OR_THROW(__proc, errorAction) \
973     CordbProcess * __proc_for_ATT = (__proc); \
974     DO_PRE_STOP_GO_CHECKS(errorAction); \
975     RSLockHolder __ch(__proc_for_ATT->GetStopGoLock()); \
976     DO_POST_STOP_GO_CHECKS(errorAction); \
977     if ((__proc_for_ATT)->GetShim() != NULL) { \
978         if (!__proc_for_ATT->m_initialized) { errorAction(CORDBG_E_NOTREADY); } \
979         if ((__proc_for_ATT)->IsStopped()) { \
980             HRESULT _hr2 = (__proc_for_ATT)->StartSyncFromWin32Stop(NULL); \
981             if (FAILED(_hr2)) errorAction(_hr2); \
982         } \
983         if (!_CORDBCheckProcessStateOKAndSync(__proc_for_ATT, NULL)) \
984             errorAction(CORDBHRFromProcessStateWorker(__proc_for_ATT, NULL, E_FAIL)); \
985     }
986
987 #define ATT_REQUIRE_STOPPED_MAY_FAIL(__proc)ATT_REQUIRE_STOPPED_MAY_FAIL_OR_THROW(__proc, return) 
988
989 // #1b - allows it to be non-inited. This should look just like ATT_REQUIRE_STOPPED_MAY_FAIL_OR_THROW
990 // except it doesn't do SSFW32Stop and doesn't have the m_initialized check.
991 #define ATT_REQUIRE_SYNCED_OR_NONINIT_MAY_FAIL(__proc) \
992     CordbProcess * __proc_for_ATT = (__proc); \
993     DO_PRE_STOP_GO_CHECKS(return); \
994     RSLockHolder __ch(__proc_for_ATT->GetStopGoLock()); \
995     DO_POST_STOP_GO_CHECKS(return); \
996     if ((__proc_for_ATT)->GetShim() != NULL) { \
997         if (!_CORDBCheckProcessStateOKAndSync(__proc_for_ATT, NULL)) \
998             return CORDBHRFromProcessStateWorker(__proc_for_ATT, NULL, E_FAIL); \
999     }
1000
1001
1002
1003 // Gross variant on #1.
1004 // This is a very dangerous ATT contract; but we need to support it for backwards compat.
1005 // Some APIs, like ICDProcess:EnumerateThreads can be used before the process is actually
1006 // initialized (kind of for interop-debugging).
1007 // These can't check the m_initialized flag b/c that may not be set yet.
1008 // They also can't sync the runtime.
1009 // This should only be used for non-blocking leaf activity.
1010 #define ATT_EVERETT_HACK_REQUIRE_STOPPED_ALLOW_NONINIT(__proc) \
1011     CordbProcess * __proc_for_ATT = (__proc); \
1012     DO_PRE_STOP_GO_CHECKS(return); \
1013     RSLockHolder __ch(__proc_for_ATT->GetStopGoLock()); \
1014     DO_POST_STOP_GO_CHECKS(return); \
1015     if (((__proc_for_ATT)->GetShim() != NULL) && !(__proc_for_ATT)->IsStopped()) { return CORDBG_E_PROCESS_NOT_SYNCHRONIZED; } \
1016
1017
1018 // #2 - caller may think debuggee is live, but throw in a Stop-Continue holder.
1019 #define ATT_ALLOW_LIVE_DO_STOPGO(__proc) \
1020     CordbProcess * __proc_for_ATT = (__proc); \
1021     DO_PRE_STOP_GO_CHECKS(return); \
1022     CORDBRequireProcessStateOK(__proc_for_ATT); \
1023     RSLockHolder __ch(__proc_for_ATT->GetStopGoLock()); \
1024     DO_POST_STOP_GO_CHECKS(return); \
1025     StopContinueHolder __hStopGo; \
1026     if ((__proc_for_ATT)->GetShim() != NULL) \
1027     { \
1028         HRESULT _hr2 = __hStopGo.Init(__proc_for_ATT); \
1029         if (FAILED(_hr2)) return _hr2; \
1030         _ASSERTE((__proc_for_ATT)->GetSynchronized()); \
1031     } \
1032
1033
1034
1035
1036 //-----------------------------------------------------------------------------
1037 // StopContinueHolder. Ensure that we're synced during a certain region.
1038 // (Particularly when sending an IPCEvent)
1039 // Calls ICorDebugProcess::Stop & IMDArocess::Continue.
1040 // Example usage:
1041 //
1042 // {
1043 //   StopContinueHolder h;
1044 //   IfFailRet(h.Init(process))
1045 //   SendIPCEvent
1046 // } // continue automatically called.
1047 //-----------------------------------------------------------------------------
1048
1049 class CordbProcess;
1050 class StopContinueHolder
1051 {
1052 public:
1053     StopContinueHolder() : m_p(NULL) { };
1054
1055     HRESULT Init(CordbProcess * p);
1056     ~StopContinueHolder();
1057
1058 protected:
1059     CordbProcess * m_p;
1060 };
1061
1062
1063 /* ------------------------------------------------------------------------- *
1064  * Base class
1065  * ------------------------------------------------------------------------- */
1066
1067 #define COM_METHOD  HRESULT STDMETHODCALLTYPE
1068
1069 typedef enum {
1070     enumCordbUnknown,       //  0
1071     enumCordb,              //  1   1  [1]x1
1072     enumCordbProcess,       //  2   1  [1]x1
1073     enumCordbAppDomain,     //  3   1  [1]x1
1074     enumCordbAssembly,      //  4
1075     enumCordbModule,        //  5   15 [27-38,55-57]x1
1076     enumCordbClass,         //  6
1077     enumCordbFunction,      //  7
1078     enumCordbThread,        //  8   2  [4,7]x1
1079     enumCordbCode,          //  9
1080     enumCordbChain,         //  10
1081     enumCordbChainEnum,     //  11
1082     enumCordbContext,       //  12
1083     enumCordbFrame,         //  13
1084     enumCordbFrameEnum,     //  14
1085     enumCordbValueEnum,     //  15
1086     enumCordbRegisterSet,   //  16
1087     enumCordbJITILFrame,    //  17
1088     enumCordbBreakpoint,    //  18
1089     enumCordbStepper,       //  19
1090     enumCordbValue,         //  20
1091     enumCordbEnCSnapshot,   //  21
1092     enumCordbEval,          //  22
1093     enumCordbUnmanagedThread,// 23
1094     enumCorpubPublish,      //  24
1095     enumCorpubProcess,      //  25
1096     enumCorpubAppDomain,    //  26
1097     enumCorpubProcessEnum,  //  27
1098     enumCorpubAppDomainEnum,//  28
1099     enumCordbEnumFilter,    //  29
1100     enumCordbEnCErrorInfo,  //  30
1101     enumCordbEnCErrorInfoEnum,//31
1102     enumCordbUnmanagedEvent,//  32
1103     enumCordbWin32EventThread,//33
1104     enumCordbRCEventThread, //  34
1105     enumCordbNativeFrame,   //  35
1106     enumCordbObjectValue,   //  36
1107     enumCordbType,          //  37
1108     enumCordbNativeCode,    //  38
1109     enumCordbILCode,        //  39
1110     enumCordbEval2,         //  40
1111     enumCordbMDA,           //  41
1112     enumCordbHashTableEnum, //  42
1113     enumCordbCodeEnum,      //  43
1114     enumCordbStackWalk,     //  44
1115     enumCordbEnumerator,    //  45
1116     enumCordbHeap,          //  48
1117     enumCordbHeapSegments,  //  47
1118     enumMaxDerived,         //
1119     enumMaxThis = 1024
1120 } enumCordbDerived;
1121
1122
1123
1124 //-----------------------------------------------------------------------------
1125 // Support for Native Breakpoints
1126 //-----------------------------------------------------------------------------
1127 struct NativePatch
1128 {
1129     void * pAddress; // pointer into the LS address space.
1130     PRD_TYPE opcode; // opcode to restore with.
1131
1132     inline bool operator==(NativePatch p2)
1133     {
1134         return memcmp(this, &p2, sizeof(p2)) == 0;
1135     }
1136 };
1137
1138 //-----------------------------------------------------------------------------
1139 // Cross-platform patch operations
1140 //-----------------------------------------------------------------------------
1141
1142 // Remove the int3 from the remote address
1143 HRESULT RemoveRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE opcode);
1144
1145 // This flavor is assuming our caller already knows the opcode.
1146 HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress);
1147
1148 // Apply the patch and get the opcode that we're replacing.
1149 HRESULT ApplyRemotePatch(CordbProcess * pProcess, const void * pRemoteAddress, PRD_TYPE * pOpcode);
1150
1151
1152 class CordbHashTable;
1153
1154 #define CORDB_COMMON_BASE_SIGNATURE 0x0d00d96a
1155 #define CORDB_COMMON_BASE_SIGNATURE_DEAD 0x0dead0b1
1156
1157 // Common base for both CorPublish + CorDebug objects.
1158 class CordbCommonBase : public IUnknown
1159 {
1160 public:
1161     // GENERIC: made this private as I'm changing the use of m_id for CordbClass, and
1162     // I want to make sure I catch all the places where m_id is used directly and cast
1163     // to/from tokens and/or (void*).
1164     UINT_PTR    m_id;
1165
1166 #ifdef _DEBUG
1167     static LONG m_saDwInstance[enumMaxDerived]; // instance x this
1168     static LONG m_saDwAlive[enumMaxDerived];
1169     static PVOID m_sdThis[enumMaxDerived][enumMaxThis];
1170     DWORD m_dwInstance;
1171     enumCordbDerived m_type;
1172 #endif
1173
1174
1175
1176 private:
1177     DWORD       m_signature : 30;
1178
1179     // Sticky bit set when we neuter an object. All methods (besides AddRef,Release,QI)
1180     // should check this bit and fail via the FAIL_IF_NEUTERED macro.
1181     DWORD        m_fIsNeutered : 1;
1182
1183     // Mark that this object can be "neutered at will". NeuterList::SweepAllNeuterAtWillObjects
1184     // looks at this bit.
1185     // For some objects, we don't explicitly mark when the lifetime is up. The only way
1186     // we know is when external count goes to 0. This avoids forcing us to do cleanup
1187     // in the dtor (which may come at a bad time). Sticky bit set in BaseRelease().
1188     DWORD        m_fNeuterAtWill : 1;
1189 public:
1190
1191     static LONG s_CordbObjectUID;    // Unique ID for each object.
1192     static LONG s_TotalObjectCount; // total number of outstanding objects.
1193
1194
1195     void ValidateObject()
1196     {
1197         if( !IsValidObject() )
1198         {
1199             STRESS_LOG1(LF_ASSERT, LL_ALWAYS, "CordbCommonBase::IsValidObject() failed: %x\n", this);
1200             _ASSERTE(!"CordbCommonBase::IsValidObject() failed");
1201             FreeBuildDebugBreak();
1202         }
1203     }
1204
1205     bool IsValidObject()
1206     {
1207         return (m_signature == CORDB_COMMON_BASE_SIGNATURE);
1208     }
1209
1210     CordbCommonBase(UINT_PTR id, enumCordbDerived type)
1211     {
1212         init(id, type);
1213     }
1214
1215     CordbCommonBase(UINT_PTR id)
1216     {
1217         init(id, enumCordbUnknown);
1218     }
1219
1220     void init(UINT_PTR id, enumCordbDerived type)
1221     {
1222         // To help us track object leaks, we want to log when we create & destory CordbBase objects.
1223 #ifdef _DEBUG
1224         InterlockedIncrement(&s_TotalObjectCount);
1225         InterlockedIncrement(&s_CordbObjectUID);
1226
1227         LOG((LF_CORDB, LL_EVERYTHING, "Memory: CordbBase object allocated: this=%p, count=%d, id=%p, Type=%d\n", this, s_CordbObjectUID, id, type));
1228 #endif
1229
1230         m_signature = CORDB_COMMON_BASE_SIGNATURE;
1231         m_fNeuterAtWill = 0;
1232         m_fIsNeutered = 0;
1233
1234         m_id = id;
1235         m_RefCount = 0;
1236
1237 #ifdef _DEBUG
1238         m_type = type;
1239         //m_dwInstance = CordbBase::m_saDwInstance[m_type];
1240         //InterlockedIncrement(&CordbBase::m_saDwInstance[m_type]);
1241         //InterlockedIncrement(&CordbBase::m_saDwAlive[m_type]);
1242         //if (m_dwInstance < enumMaxThis)
1243         //{
1244         //    m_sdThis[m_type][m_dwInstance] = this;
1245         //}
1246 #endif
1247     }
1248
1249     virtual ~CordbCommonBase()
1250     {
1251         // If we're deleting, we really should have released any outstanding reference.
1252         // If we call Release() on a deleted object, we'll av (especially b/c Release
1253         // may call delete again).
1254         CONSISTENCY_CHECK_MSGF(m_RefCount == 0, ("Deleting w/ non-zero ref count. 0x%08x", m_RefCount));
1255
1256 #ifdef _DEBUG
1257         //InterlockedDecrement(&CordbBase::m_saDwAlive[m_type]);
1258         //if (m_dwInstance < enumMaxThis)
1259         //{
1260         //    m_sdThis[m_type][m_dwInstance] = NULL;
1261         //}
1262 #endif
1263         // To help us track object leaks, we want to log when we create & destory CordbBase objects.
1264         LOG((LF_CORDB, LL_EVERYTHING, "Memory: CordbBase object deleted: this=%p, id=%p, Refcount=0x%x\n", this, m_id, m_RefCount));
1265
1266 #ifdef _DEBUG
1267         InterlockedDecrement(&s_TotalObjectCount);
1268         _ASSERTE(s_TotalObjectCount >= 0);
1269 #endif
1270
1271         // Don't shutdown logic until everybody is done with it.
1272         // If we leak objects, this may mean that we never shutdown logging at all!
1273 #if defined(_DEBUG) && defined(LOGGING)
1274         if (s_TotalObjectCount == 0)
1275         {
1276             ShutdownLogging();
1277         }
1278 #endif
1279     }
1280
1281     /*
1282         Member function behavior of a neutered COM object:
1283
1284              1. AddRef(), Release(), QueryInterface() work as normal.
1285                  a. This gives folks who are responsible for pairing a Release() with
1286                     an AddRef() a chance to dereference their pointer and call Release()
1287                     when they are informed, explicitly or implicitly, that the object is neutered.
1288
1289              2. Any other member function will return an error code unless documented.
1290                  a. If a member function returns information when the COM object is
1291                     neutered then the semantics of that function need to be documented.
1292                     (ie. If an AppDomain is unloaded and you have a reference to the COM
1293                     object representing the AppDomain, how _should_ it behave? That behavior
1294                     should be documented)
1295
1296
1297         Postcondions of Neuter():
1298
1299              1. All circular references (aka back-pointers) are "broken". They are broken
1300                 by calling Release() on all "Weak References" to the object. If you're a purist,
1301                 these pointers should also be NULLed out.
1302                  a. Weak References/Strong References:
1303                      i. If any objects are not "reachable" from the root (ie. stack or from global pointers)
1304                          they should be reclaimed. If they are not, they are leaked and there is an issue.
1305                      ii. There must be a partial order on the objects such that if A < B then:
1306                          1. A has a reference to B. This reference is a "strong reference"
1307                          2. A, and thus B, is reachable from the root
1308                      iii. If a reference belongs in the partial order then it is a "strong reference" else
1309                          it is a weak reference.
1310          *** 2. Sufficient conditions to ensure no COM objects are leaked: ***
1311                 a. When Neuter() is invoked:
1312                      i. Calles Release on all its weak references.
1313                      ii. Then, for each strong reference:
1314                          1. invoke Neuter()
1315                          2. invoke Release()
1316                      iii. If it's derived from a CordbXXX class, call Neuter() on the base class.
1317                          1. Sense Neuter() is virtual, use the scope specifier Cordb[BaseClass]::Neuter().
1318              3. All members return error codes, except:
1319                  a. Members of IUknown, AddRef(), Release(), QueryInterfac()
1320                  b. Those documented to have functionality when the object is neutered.
1321                      i. Neuter() still works w/o error. If it is invoke a second time it will have already
1322                         released all its strong and weak references so it could just return.
1323
1324
1325         Alternate design ideas:
1326
1327              DESIGN: Note that it's possible for object B to have two parents in the partial order
1328                      and it must be documented which one is responsible for calling Neuter() on B.
1329                       1. For example, CordbCode could reasonably be a sibling of CordbFunction and CordbNativeFrame.
1330                          Which one should call Release()? For now we have CordbFunction call Release() on CordbCode.
1331
1332              DESIGN: It is not a necessary condition in that Neuter() invoke Release() on all
1333                      it's strong references. Instead, it would be sufficient to ensure all object are released, that
1334                      each object call Release() on all its strong pointers in its destructor.
1335                       1. This might be done if its necessary for some member to return "tombstone"
1336                          information after the object has been netuered() which involves the siblings (wrt poset)
1337                          of the object. However, no sibling could access a parent (wrt poset) because
1338                          Neuter called Release() on all its weak pointers.
1339
1340              DESIGN: Rename Neuter() to some name that more accurately reflect the semantics.
1341                      1. The three operations are:
1342                          a. ReleaseWeakPointers()
1343                          b. NeuterStrongPointers()
1344                          c. ReleaseStrongPointers()
1345                              1. Assert that it's done after NeuterStrongPointers()
1346                      2. That would introduce a bunch of functions... but it would be clear.
1347
1348              DESIGN: CordbBase could provide a function to register strong and weak references. That way CordbBase
1349                      could implement a general version of ReleaseWeak/ReleaseStrong/NeuterStrongPointers(). This
1350                      would provide a very error resistant framework for extending the object model plus it would
1351                      be very explicit about what is going on.
1352                          One thing that might trip this is idea up is that if an object has two parents,
1353                          like the CordbCode might, then either both objects call Neuter or one is reference
1354                          is made weak.
1355
1356
1357         Our implementation:
1358
1359            The graph formed by the strong references must remain acyclic.
1360            It's up to the developer (YOU!) to ensure that each Neuter
1361            function maintains that invariant.
1362
1363            Here is the current Partial Order on CordbXXX objects. (All these classes
1364            eventually chain to CordbBase.Neuter() for completeness.)
1365
1366            Cordb
1367               CordbProcess
1368                   CordbAppDomain
1369                       CordbBreakPoints
1370                       CordbAssembly
1371                       CordbModule
1372                           CordbClass
1373                           CordbFunction
1374                               CordbCode (Can we assert a thread will not reference
1375                                           the same CordbCode as a CordbFunction?)
1376                  CordbThread
1377                      CordbChains
1378                      CordbNativeFrame -> CordbFrame (Chain to baseClass)
1379                          CordbJITILFrame
1380
1381
1382             <TODO>TODO: Some Neuter functions have not yet been implemented due to time restrictions.</TODO>
1383
1384             <TODO>TODO: Some weak references never have AddRef() called on them. If that's cool then
1385                   it should be stated in the documentation. Else it should be changed.</TODO>
1386 */
1387
1388     virtual void Neuter();
1389
1390     // Unsafe neuter for an object that's already dead.
1391     void UnsafeNeuterDeadObject();
1392
1393
1394 #ifdef _DEBUG
1395     // For debugging (asserts, logging, etc) provide a pretty name (this is 1:1 w/ the VTable)
1396     // We provide a default impl in the base object in case this gets called from a dtor (virtuals
1397     // called from dtors use the base version, not the derived). A pure call would AV in that case.
1398     virtual const char * DbgGetName() { return "CordbBase"; };
1399 #endif
1400
1401     bool IsNeutered() const {LIMITED_METHOD_CONTRACT;  return m_fIsNeutered == 1; }
1402     bool IsNeuterAtWill() const { LIMITED_METHOD_CONTRACT; return m_fNeuterAtWill == 1; }
1403     void MarkNeuterAtWill() { LIMITED_METHOD_CONTRACT; m_fNeuterAtWill = 1; }
1404
1405     //-----------------------------------------------------------
1406     // IUnknown support
1407     //----------------------------------------------------------
1408
1409 private:
1410     // We maintain both an internal + external refcount. This allows us to catch
1411     // if an external caller has too many releases.
1412     // low  bits are internal count, high  bits are external count
1413     // so Total count = (m_RefCount & CordbBase_InternalRefCountMask) + (m_RefCount >> CordbBase_ExternalRefCountShift);
1414     typedef LONGLONG       MixedRefCountSigned;
1415     typedef ULONGLONG      MixedRefCountUnsigned;
1416     typedef LONG           ExternalRefCount;
1417     MixedRefCountUnsigned  m_RefCount;
1418 public:
1419
1420     // Adjust the internal ref count.
1421     // These aren't available to the external world, so only internal code can manipulate the internal count.
1422     void InternalAddRef();
1423     void InternalRelease();
1424
1425     // Derived versions of AddRef / Release will call these.
1426     // External AddRef & Release
1427     // These do not have any additional Asserts to enforce that we're not manipulating the external count
1428     // from internal.
1429     ULONG STDMETHODCALLTYPE BaseAddRef();
1430     ULONG STDMETHODCALLTYPE BaseRelease();
1431
1432     // External ref count versions, with extra debug count to enforce that this is done externally.
1433     // When derive classes use these versions, it Asserts that we're not adjusting external counts from inside.
1434     // Thus we can be confident that we're *never* leaking external refs to these objects.
1435     // @todo - eventually everything should use these.
1436     ULONG STDMETHODCALLTYPE BaseAddRefEnforceExternal();
1437     ULONG STDMETHODCALLTYPE BaseReleaseEnforceExternal();
1438
1439     // Do an AddRef against the External count. This is a semantics issue.
1440     // We use this when an internal component Addrefs out-parameters (which Cordbg will call Release on).
1441     // This just does a regular external AddRef().
1442     void ExternalAddRef();
1443
1444 protected:
1445
1446     static void InitializeCommon();
1447
1448 private:
1449     static void AddDebugPrivilege();
1450 };
1451
1452 #define CordbBase_ExternalRefCountShift 32
1453 #define CordbBase_InternalRefCountMask 0xFFFFFFFF
1454 #define CordbBase_InternalRefCountMax  0x7FFFFFFF
1455
1456 #ifdef _DEBUG
1457 // Does the given Cordb object type have affinity to a CordbProcess object?
1458 // This is only used for certain asserts.
1459 inline bool DoesCordbObjectTypeHaveProcessPtr(enumCordbDerived type)
1460 {
1461     return 
1462         (type != enumCordbCodeEnum) &&
1463         (type != enumCordb) &&
1464         (type != enumCordbHashTableEnum);
1465 }
1466 #endif
1467
1468 // Base class specifically for CorDebug objects
1469 class CordbBase : public CordbCommonBase
1470 {
1471 public:
1472     CordbBase(CordbProcess * pProcess, UINT_PTR id, enumCordbDerived type) : CordbCommonBase(id, type)
1473     {
1474         // CordbProcess can't pass 'this' to base class, per error C4355. So we pass null and set later.
1475         _ASSERTE((pProcess != NULL) || 
1476             ((type) == enumCordbProcess) ||
1477             !DoesCordbObjectTypeHaveProcessPtr(type));
1478
1479         m_pProcess.Assign(pProcess);
1480     }
1481
1482     CordbBase(CordbProcess * pProcess, UINT_PTR id) : CordbCommonBase(id)
1483     {
1484         _ASSERTE(pProcess != NULL);
1485         m_pProcess.Assign(pProcess);
1486     }
1487
1488     virtual ~CordbBase()
1489     {
1490         // Derived classes should not have cleared out our pointer.
1491         // CordbProcess's Neuter explicitly nulls out its pointer to avoid circular reference.
1492         _ASSERTE(m_pProcess!= NULL || 
1493             (CordbCommonBase::m_type == enumCordbProcess) ||
1494             !DoesCordbObjectTypeHaveProcessPtr(CordbCommonBase::m_type));
1495         
1496         // Ideally, all CorDebug objects to be neutered by the time their dtor is called.
1497         // @todo - we're still working out neutering semantics for a few remaining objects, so we exclude
1498         // those from the assert.
1499         _ASSERTE(IsNeutered() ||
1500             (m_type == enumCordbBreakpoint) ||
1501             (m_type == enumCordbStepper));
1502     }
1503
1504     // Neuter just the right-side state.
1505     virtual void Neuter();
1506
1507     // Neuter both left-side state and right-side state.
1508     virtual void NeuterLeftSideResources();
1509
1510     // Get the CordbProcess object that this CordbBase object is associated with (or NULL if there's none).
1511     CordbProcess * GetProcess() const
1512     {
1513         return m_pProcess;
1514     }
1515 protected:
1516     // All objects need a strong pointer back to the process so that they can get access to key locks
1517     // held by the process (StopGo lock) so that they can synchronize their operations against neutering.
1518     // This pointer is cleared in our dtor, and not when we're neutered. Since we can't control when the
1519     // dtor is called (it's controlled by external references), we classify this as an external reference too.
1520     //
1521     // This is the only "strong" reference backpointer that objects need have. All other backpointers can be weak references
1522     // because when a parent object is neutered, it will null out all weak reference pointers in all of its children.
1523     // That will also break any potential cycles.     
1524     RSUnsafeExternalSmartPtr<CordbProcess> m_pProcess;
1525
1526 };
1527
1528
1529
1530
1531
1532 //-----------------------------------------------------------------------------
1533 // Macro to check if a CordbXXX object is neutered, and return a standard
1534 // error code if it is.
1535 // We pass the 'this' pointer of the object in because it gives us some extra
1536 // flexibility and lets us log debug info.
1537 // It is an API breach to access a neutered object.
1538 //-----------------------------------------------------------------------------
1539 #define FAIL_IF_NEUTERED(pThis) \
1540 int _____Neuter_Status_Already_Marked; \
1541 _____Neuter_Status_Already_Marked = 0; \
1542 {\
1543     if (pThis->IsNeutered()) { \
1544             LOG((LF_CORDB, LL_ALWAYS, "Accessing a neutered object at %p\n", pThis)); \
1545             return ErrWrapper(CORDBG_E_OBJECT_NEUTERED); \
1546     } \
1547 }
1548
1549 //-----------------------------------------------------------------------------
1550 // Macro to check if a CordbXXX object is neutered, and return a standard
1551 // error code if it is.
1552 // We pass the 'this' pointer of the object in because it gives us some extra
1553 // flexibility and lets us log debug info.
1554 // It is an API breach to access a neutered object.
1555 //-----------------------------------------------------------------------------
1556 #define THROW_IF_NEUTERED(pThis) \
1557 int _____Neuter_Status_Already_Marked; \
1558 _____Neuter_Status_Already_Marked = 0; \
1559 {\
1560     if (pThis->IsNeutered()) { \
1561             LOG((LF_CORDB, LL_ALWAYS, "Accessing a neutered object at %p\n", pThis)); \
1562             ThrowHR(CORDBG_E_OBJECT_NEUTERED); \
1563     } \
1564 }
1565
1566 // We have an OK_IF_NEUTERED macro to say that this method can be safely
1567 // called if we're neutered. Mostly for semantic benefits.
1568 // Also, if a method is marked OK, then somebody won't go and add a 'fail'
1569 // This is an extremely dangerous quality because:
1570 // 1) it means that we have no synchronization (can't take the Stop-Go lock)
1571 // 2) none of our backpointers are usable (they may be nulled out at anytime by another thread).
1572 //    - this also means we absolutely can't send IPC events (since that requires a CordbProcess)
1573 // 3) The only safe data are blittalbe embedded fields (eg, a pid or stack range) 
1574 //
1575 // Any usage of this macro should clearly specify why this is safe.
1576 #define OK_IF_NEUTERED(pThis) \
1577 int _____Neuter_Status_Already_Marked; \
1578 _____Neuter_Status_Already_Marked = 0;
1579
1580
1581 //-------------------------------------------------------------------------------
1582 // Simple COM enumerator pattern on a fixed list of items
1583 //--------------------------------------------------------------------------------
1584 template< typename ElemType,
1585           typename ElemPublicType,
1586           typename EnumInterfaceType,
1587           ElemPublicType (*GetPublicType)(ElemType)>
1588 class CordbEnumerator : public CordbBase, EnumInterfaceType
1589 {
1590 private:
1591     // the list of items being enumerated over
1592     ElemType *m_items;
1593     // the number of items in the list
1594     DWORD m_countItems;
1595     // the index of the next item to be returned in the enumeration
1596     DWORD m_nextIndex;
1597
1598 public:
1599     // makes a copy of the elements in the "items" array
1600     CordbEnumerator(CordbProcess* pProcess, ElemType *items, DWORD elemCount);
1601     // assumes ownership of the elements in the "*items" array.
1602     // this avoids an extra allocation + copy
1603     CordbEnumerator(CordbProcess* pProcess, ElemType **items, DWORD elemCount);
1604     ~CordbEnumerator();
1605
1606 // IUnknown interface
1607     virtual COM_METHOD QueryInterface(REFIID riid, VOID** ppInterface);
1608     virtual ULONG __stdcall AddRef();
1609     virtual ULONG __stdcall Release();
1610
1611 // ICorDebugEnum interface
1612     virtual COM_METHOD Clone(ICorDebugEnum **ppEnum);
1613     virtual COM_METHOD GetCount(ULONG *pcelt);
1614     virtual COM_METHOD Reset();
1615     virtual COM_METHOD Skip(ULONG celt);
1616
1617 // ICorDebugXXXEnum interface
1618     virtual COM_METHOD Next(ULONG celt, ElemPublicType items[], ULONG *pceltFetched);
1619
1620 // CordbBase overrides
1621     virtual VOID Neuter();
1622 };
1623
1624 // Converts T to U* by using QueryInterface
1625 template<typename T, typename U>
1626 U* QueryInterfaceConvert(T obj);
1627
1628 // No conversion, just returns the argument
1629 template<typename T>
1630 T IdentityConvert(T obj);
1631
1632 // CorDebugGuidToTypeMapping-adapter used by CordbGuidToTypeEnumerator 
1633 // in the CordbEnumerator pattern
1634 struct RsGuidToTypeMapping
1635 {
1636     GUID iid;
1637     RSSmartPtr<CordbType> spType;
1638 };
1639
1640 inline
1641 CorDebugGuidToTypeMapping GuidToTypeMappingConvert(RsGuidToTypeMapping m)
1642 {
1643     CorDebugGuidToTypeMapping result;
1644     result.iid = m.iid;
1645     result.pType = (ICorDebugType*)(m.spType.GetValue());
1646     result.pType->AddRef();
1647     return result;
1648 }
1649
1650 //
1651 // Some useful enumerators
1652 //
1653 typedef CordbEnumerator<RSSmartPtr<CordbThread>,
1654                         ICorDebugThread*,
1655                         ICorDebugThreadEnum,
1656                         QueryInterfaceConvert<RSSmartPtr<CordbThread>, ICorDebugThread> > CordbThreadEnumerator;
1657
1658 typedef CordbEnumerator<CorDebugBlockingObject,
1659                         CorDebugBlockingObject,
1660                         ICorDebugBlockingObjectEnum,
1661                         IdentityConvert<CorDebugBlockingObject> > CordbBlockingObjectEnumerator;
1662
1663 // Template classes must be fully defined rather than just declared in the header
1664 #include "rsenumerator.hpp"
1665
1666
1667 typedef CordbEnumerator<COR_SEGMENT,
1668                         COR_SEGMENT,
1669                         ICorDebugHeapSegmentEnum,
1670                         IdentityConvert<COR_SEGMENT> > CordbHeapSegmentEnumerator;
1671
1672 typedef CordbEnumerator<CorDebugExceptionObjectStackFrame,
1673                         CorDebugExceptionObjectStackFrame,
1674                         ICorDebugExceptionObjectCallStackEnum,
1675                         IdentityConvert<CorDebugExceptionObjectStackFrame> > CordbExceptionObjectCallStackEnumerator;
1676
1677 typedef CordbEnumerator<RsGuidToTypeMapping,
1678                         CorDebugGuidToTypeMapping,
1679                         ICorDebugGuidToTypeEnum,
1680                         GuidToTypeMappingConvert > CordbGuidToTypeEnumerator;
1681
1682 // ----------------------------------------------------------------------------
1683 // Hash table for CordbBase objects.
1684 // - Uses Internal AddRef/Release (not external)
1685 // - Templatize for type-safety w/ Cordb objects
1686 // - Many hashtables are implicitly protected by a lock. For debug-only, we
1687 //   explicitly associate w/ an optional RSLock and assert that lock is held on access.
1688 // ----------------------------------------------------------------------------
1689
1690 struct CordbHashEntry
1691 {
1692     FREEHASHENTRY entry;
1693     CordbBase *pBase;
1694 };
1695
1696 class CordbHashTable : private CHashTableAndData<CNewDataNoThrow>
1697 {
1698 private:
1699     bool    m_initialized;
1700     SIZE_T  m_count;
1701
1702     BOOL Cmp(SIZE_T k1, const HASHENTRY * pc2)
1703     {
1704         LIMITED_METHOD_CONTRACT;
1705
1706         return ((ULONG_PTR)k1) != (reinterpret_cast<const CordbHashEntry *>(pc2))->pBase->m_id;
1707     }
1708
1709     ULONG HASH(ULONG_PTR id)
1710     {
1711         return (ULONG)(id);
1712     }
1713
1714     SIZE_T KEY(UINT_PTR id)
1715     {
1716         return (SIZE_T)id;
1717     }
1718
1719 public:
1720     bool IsInitialized();
1721
1722 #ifndef DACCESS_COMPILE
1723     CordbHashTable(ULONG size)
1724     : CHashTableAndData<CNewDataNoThrow>(size), m_initialized(false), m_count(0)
1725     {
1726 #ifdef _DEBUG
1727     m_pDbgLock = NULL;
1728     m_dbgChangeCount = 0;
1729 #endif
1730     }
1731     virtual ~CordbHashTable();
1732
1733 #ifdef _DEBUG
1734     // CordbHashTables may be protected by a lock. For debug-builds, we can associate
1735     // the hash w/ that lock and then assert if it's not held.
1736     void DebugSetRSLock(RSLock * pLock)
1737     {
1738         m_pDbgLock = pLock;
1739     }
1740     int GetChangeCount() { return m_dbgChangeCount; }
1741 private:
1742     void AssertIsProtected();
1743
1744     // Increment the Change count. This can be used to check if the hashtable changes while being enumerated.
1745     void DbgIncChangeCount() { m_dbgChangeCount++; }
1746
1747     int m_dbgChangeCount;
1748     RSLock * m_pDbgLock;
1749 #else
1750     // RSLock association is a no-op on free builds.
1751     void AssertIsProtected() { };
1752     void DbgIncChangeCount() { };
1753 #endif // _DEBUG
1754
1755 public:
1756
1757
1758 #endif
1759
1760     ULONG32 GetCount()
1761     {
1762         return ((ULONG32)m_count);
1763     }
1764
1765     // These operators are unsafe b/c they have no typesafety.
1766     // Use a derived CordbSafeHashTable<T> instead.
1767     HRESULT UnsafeAddBase(CordbBase *pBase);
1768     HRESULT UnsafeSwapBase(CordbBase* pBaseOld, CordbBase* pBaseNew);
1769     CordbBase *UnsafeGetBase(ULONG_PTR id, BOOL fFab = TRUE);
1770     CordbBase *UnsafeRemoveBase(ULONG_PTR id);
1771
1772     CordbBase *UnsafeFindFirst(HASHFIND *find);
1773     CordbBase *UnsafeFindNext(HASHFIND *find);
1774
1775     // Unlocked versions don't assert that the lock us held.
1776     CordbBase *UnsafeUnlockedFindFirst(HASHFIND *find);
1777     CordbBase *UnsafeUnlockedFindNext(HASHFIND *find);
1778
1779 };
1780
1781
1782 // Typesafe wrapper around a normal hash table
1783 // T is expected to be a derived clas of CordbBase
1784 // Note that this still isn't fully typesafe.  Ideally we'd take a strongly-typed key
1785 // instead of UINT_PTR (the type could have a fixed relationship to T, or could be
1786 // an additional template argument like standard template hash tables like std::hash_map<K,V>)
1787 template <class T>
1788 class CordbSafeHashTable : public CordbHashTable
1789 {
1790 public:
1791 #ifndef DACCESS_COMPILE
1792     CordbSafeHashTable<T>(ULONG size) : CordbHashTable(size)
1793     {
1794     }
1795 #endif
1796     // Typesafe wrappers
1797     HRESULT AddBase(T * pBase) { return UnsafeAddBase(pBase); }
1798
1799     // Either add (eg, future cals to GetBase will succeed) or throw. 
1800     void AddBaseOrThrow(T * pBase)
1801     {
1802         HRESULT hr = AddBase(pBase);
1803         IfFailThrow(hr);
1804     }
1805     HRESULT SwapBase(T* pBaseOld, T* pBaseNew) { return UnsafeSwapBase(pBaseOld, pBaseNew); }
1806     // Move the function definition of GetBase to rspriv.inl to work around gcc 2.9.5 warnings
1807     T* GetBase(ULONG_PTR id, BOOL fFab = TRUE);
1808     T* GetBaseOrThrow(ULONG_PTR id, BOOL fFab = TRUE);
1809
1810     T* RemoveBase(ULONG_PTR id) { return static_cast<T*>(UnsafeRemoveBase(id)); }
1811
1812     T* FindFirst(HASHFIND *find) { return static_cast<T*>(UnsafeFindFirst(find)); }
1813     T* FindNext(HASHFIND *find)  { return static_cast<T*>(UnsafeFindNext(find)); }
1814
1815     // Neuter all items and clear
1816     void NeuterAndClear(RSLock * pLock);
1817
1818     void CopyToArray(RSPtrArray<T> * pArray);
1819     void TransferToArray(RSPtrArray<T> * pArray);
1820 };
1821
1822
1823 class CordbHashTableEnum : public CordbBase,
1824 public ICorDebugProcessEnum,
1825 public ICorDebugBreakpointEnum,
1826 public ICorDebugStepperEnum,
1827 public ICorDebugThreadEnum,
1828 public ICorDebugModuleEnum,
1829 public ICorDebugAppDomainEnum,
1830 public ICorDebugAssemblyEnum
1831 {
1832     // Private ctors. Use build function to access.
1833     CordbHashTableEnum(
1834         CordbBase * pOwnerObj, 
1835         NeuterList * pOwnerList, 
1836         CordbHashTable *table,
1837         const _GUID &id);
1838
1839 public:
1840     static void BuildOrThrow(
1841         CordbBase * pOwnerObj, 
1842         NeuterList * pOwnerList, 
1843         CordbHashTable *table,
1844         const _GUID &id,
1845         RSInitHolder<CordbHashTableEnum> * pHolder);
1846
1847     CordbHashTableEnum(CordbHashTableEnum *cloneSrc);
1848
1849     ~CordbHashTableEnum();
1850     virtual void Neuter();
1851
1852
1853 #ifdef _DEBUG
1854     // For debugging (asserts, logging, etc) provide a pretty name (this is 1:1 w/ the VTable)
1855     virtual const char * DbgGetName() { return "CordbHashTableEnum"; };
1856 #endif
1857
1858
1859     HRESULT Next(ULONG celt, CordbBase *bases[], ULONG *pceltFetched);
1860
1861     //-----------------------------------------------------------
1862     // IUnknown
1863     //-----------------------------------------------------------
1864
1865     ULONG STDMETHODCALLTYPE AddRef()
1866     {
1867         return (BaseAddRef());
1868     }
1869     ULONG STDMETHODCALLTYPE Release()
1870     {
1871         return (BaseRelease());
1872     }
1873     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
1874
1875     //-----------------------------------------------------------
1876     // ICorDebugEnum
1877     //-----------------------------------------------------------
1878
1879     COM_METHOD Skip(ULONG celt);
1880     COM_METHOD Reset();
1881     COM_METHOD Clone(ICorDebugEnum **ppEnum);
1882     COM_METHOD GetCount(ULONG *pcelt);
1883
1884     //-----------------------------------------------------------
1885     // ICorDebugProcessEnum
1886     //-----------------------------------------------------------
1887
1888     COM_METHOD Next(ULONG celt, ICorDebugProcess *processes[],
1889                     ULONG *pceltFetched)
1890     {
1891         VALIDATE_POINTER_TO_OBJECT_ARRAY(processes, ICorDebugProcess *,
1892             celt, true, true);
1893         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1894
1895         return (Next(celt, (CordbBase **)processes, pceltFetched));
1896     }
1897
1898     //-----------------------------------------------------------
1899     // ICorDebugBreakpointEnum
1900     //-----------------------------------------------------------
1901
1902     COM_METHOD Next(ULONG celt, ICorDebugBreakpoint *breakpoints[],
1903                     ULONG *pceltFetched)
1904     {
1905         VALIDATE_POINTER_TO_OBJECT_ARRAY(breakpoints, ICorDebugBreakpoint *,
1906             celt, true, true);
1907         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1908
1909         return (Next(celt, (CordbBase **)breakpoints, pceltFetched));
1910     }
1911
1912     //-----------------------------------------------------------
1913     // ICorDebugStepperEnum
1914     //-----------------------------------------------------------
1915
1916     COM_METHOD Next(ULONG celt, ICorDebugStepper *steppers[],
1917                     ULONG *pceltFetched)
1918     {
1919         VALIDATE_POINTER_TO_OBJECT_ARRAY(steppers, ICorDebugStepper *,
1920             celt, true, true);
1921         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1922
1923         return (Next(celt, (CordbBase **)steppers, pceltFetched));
1924     }
1925
1926     //-----------------------------------------------------------
1927     // ICorDebugThreadEnum
1928     //-----------------------------------------------------------
1929
1930     COM_METHOD Next(ULONG celt, ICorDebugThread *threads[],
1931                     ULONG *pceltFetched)
1932     {
1933         VALIDATE_POINTER_TO_OBJECT_ARRAY(threads, ICorDebugThread *,
1934             celt, true, true);
1935         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1936
1937         return (Next(celt, (CordbBase **)threads, pceltFetched));
1938     }
1939
1940     //-----------------------------------------------------------
1941     // ICorDebugModuleEnum
1942     //-----------------------------------------------------------
1943
1944     COM_METHOD Next(ULONG celt, ICorDebugModule *modules[],
1945                     ULONG *pceltFetched)
1946     {
1947         VALIDATE_POINTER_TO_OBJECT_ARRAY(modules, ICorDebugModule *,
1948             celt, true, true);
1949         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1950
1951         return (Next(celt, (CordbBase **)modules, pceltFetched));
1952     }
1953
1954     //-----------------------------------------------------------
1955     // ICorDebugAppDomainEnum
1956     //-----------------------------------------------------------
1957
1958     COM_METHOD Next(ULONG celt, ICorDebugAppDomain *appdomains[],
1959                     ULONG *pceltFetched)
1960     {
1961         VALIDATE_POINTER_TO_OBJECT_ARRAY(appdomains, ICorDebugAppDomain *,
1962             celt, true, true);
1963         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1964
1965         return (Next(celt, (CordbBase **)appdomains, pceltFetched));
1966     }
1967     //-----------------------------------------------------------
1968     // ICorDebugAssemblyEnum
1969     //-----------------------------------------------------------
1970
1971     COM_METHOD Next(ULONG celt, ICorDebugAssembly *assemblies[],
1972                     ULONG *pceltFetched)
1973     {
1974         VALIDATE_POINTER_TO_OBJECT_ARRAY(assemblies, ICorDebugAssembly *,
1975             celt, true, true);
1976         VALIDATE_POINTER_TO_OBJECT(pceltFetched, ULONG *);
1977
1978         return (Next(celt, (CordbBase **)assemblies, pceltFetched));
1979     }
1980 private:
1981     // Owning object is our link to the CordbProcess* tree. Never null until we're neutered.
1982     // NeuterList is related to the owning object. Need to cache it so that we can pass it on
1983     // to our clones.
1984     CordbBase *     m_pOwnerObj; // provides us w/ a CordbProcess*
1985     NeuterList *    m_pOwnerNeuterList;
1986
1987
1988     CordbHashTable *m_table;
1989     bool            m_started;
1990     bool            m_done;
1991     HASHFIND        m_hashfind;
1992     REFIID          m_guid;
1993     ULONG           m_iCurElt;
1994     ULONG           m_count;
1995     BOOL            m_fCountInit;
1996
1997 #ifdef _DEBUG
1998     // timestampt of hashtable when we start enumerating it. Useful for detecting if the table
1999     // changes underneath us.
2000     int             m_DbgChangeCount;
2001     void AssertValid();
2002 #else
2003     void AssertValid() { }
2004 #endif
2005
2006 private:
2007     //These factor code between Next & Skip
2008     HRESULT PrepForEnum(CordbBase **pBase);
2009
2010     // Note that the set of types advanced by Pre & by Post are disjoint, and
2011     // that the union of these two sets are all possible types enuerated by
2012     // the CordbHashTableEnum.
2013     HRESULT AdvancePreAssign(CordbBase **pBase);
2014     HRESULT AdvancePostAssign(CordbBase **pBase,
2015                               CordbBase     **b,
2016                               CordbBase   **bEnd);
2017
2018     // This factors some code that initializes the module enumerator.
2019     HRESULT SetupModuleEnum();
2020
2021 };
2022
2023
2024 //-----------------------------------------------------------------------------
2025 // Neuter List
2026 // Dtors can be called at any time (whenever Cordbg calls Release, which is outside
2027 // of our control), so we never want to do significant work in a dtor
2028 // (this includes sending IPC events + neutering).
2029 // So objects can queue themselves up to be neutered at a safe time.
2030 // 
2031 // Items in a NeuterList should only contain state in the Right-Side.
2032 // If the item holds resources in the left-side, it should be placed on a
2033 // code:LeftSideResourceCleanupList 
2034 //-----------------------------------------------------------------------------
2035 class NeuterList
2036 {
2037 public:
2038     NeuterList();
2039     ~NeuterList();
2040
2041     // Add an object to be neutered.
2042     // Anybody calls this to add themselves to the list.
2043     // This will add it to the list and maintain an internal reference to it.
2044     void Add(CordbProcess * pProcess, CordbBase * pObject);
2045
2046     // Add w/o checking for safety. Should only be used by Process-list enum.
2047     void UnsafeAdd(CordbProcess * pProcess, CordbBase * pObject);
2048
2049     // Neuter everything on the list.
2050     // This should only be called by the "owner", but we can't really enforce that.
2051     // This will release all internal references and empty the list.
2052     void NeuterAndClear(CordbProcess * pProcess);
2053
2054     // Sweep for all objects that are marked as 'm_fNeuterAtWill'.
2055     // Neuter and remove these.
2056     void SweepAllNeuterAtWillObjects(CordbProcess * pProcess);
2057
2058 protected:
2059     struct Node
2060     {
2061         RSSmartPtr<CordbBase> m_pObject;
2062         Node * m_pNext;
2063     };
2064
2065     // Manipulating the list is done under the Process lock.
2066     Node * m_pHead;
2067 };
2068
2069 //-----------------------------------------------------------------------------
2070 // This list is for objects that hold left-side resources. 
2071 // If the object does not hold left-side resources, it can be placed on a
2072 // code:NeuterList
2073 //-----------------------------------------------------------------------------
2074 class LeftSideResourceCleanupList : public NeuterList
2075 {
2076 public:
2077     // dispose everything contained in the list by calling SafeDispose() on each element
2078     void SweepNeuterLeftSideResources(CordbProcess * pProcess);
2079     void NeuterLeftSideResourcesAndClear(CordbProcess * pProcess);
2080 };
2081
2082 //-------------------------------------------------------------------------
2083 //
2084 // Optional<T>
2085 // Stores a value along with a bit indicating whether the value is valid.
2086 //
2087 // This is particularly useful for LS data read via DAC.  We need to gracefully
2088 // handle missing data, and we may want to track independent pieces of data
2089 // separately (often with lazy initialization).  It's essential that we can't
2090 // easily lose track of whether the data has been cached yet or not.  So 
2091 // rather than have extra "isValid" bools everywhere, we use this class to
2092 // encapsulate the validity bit in with the data, and ASSERT that it is true
2093 // whenever reading out the data.
2094 // Note that the client must still remember to call GetValue only when HasValue 
2095 // is true.  Since C++ doesn't have type-safe sum types, we can't enforce this
2096 // explicitly at compile time (ML-style datatypes and pattern matching is perfect
2097 // for this).
2098 //
2099 // Note that we could consider adding some operator overloads to make using 
2100 // instances of this class more transparent.  Experience will tell if this
2101 // is a good idea or not.
2102 //
2103 template <typename T>
2104 class Optional
2105 {
2106 public:
2107     // By default, initialize to invalid 
2108     Optional() : m_fHasValue(false), m_value(T()) {}
2109
2110     // Allow implicit initialization from a value (for copyable T)
2111     Optional(const T& val) : m_fHasValue(true), m_value(val) {}
2112
2113     // Returns true if a value has been stored
2114     bool HasValue() const    { return m_fHasValue; }
2115
2116     // Extract the value.  Can only be called when HasValue is true.
2117     const T& GetValue()        { _ASSERTE(m_fHasValue); return m_value; }
2118
2119     // Get a writable pointer to the value structure, for filling in uncopyable data structures
2120     T * GetValueAddr() { return &m_value; }
2121
2122     // Explicitly mark this object as having a value (for use after writing to it directly using
2123     // GetValueAddr.  Not necessary for simple/primitive types).
2124     void SetHasValue() { m_fHasValue = true; }
2125
2126     // Also gets compiler-default copy constructor and assignment operator if T has them
2127
2128 private:
2129     bool m_fHasValue;
2130     T m_value;
2131 };
2132
2133
2134 /* ------------------------------------------------------------------------- *
2135  * Cordb class
2136  * ------------------------------------------------------------------------- */
2137
2138 class Cordb : public CordbBase, public ICorDebug, public ICorDebugRemote
2139 {
2140 public:
2141     Cordb(CorDebugInterfaceVersion iDebuggerVersion);
2142     virtual ~Cordb();
2143     virtual void Neuter();
2144
2145
2146
2147 #ifdef _DEBUG_IMPL
2148     virtual const char * DbgGetName() { return "Cordb"; }
2149
2150     // Under Debug, we keep some extra state for tracking leaks. The goal is that
2151     // we can assert that we aren't leaking internal refs. We'd like to assert that
2152     // we're not leaking external refs, but since we can't force Cordbg to release,
2153     // we can't really assert that.
2154     // So the idea is that when Cordbg has released its last Cordb object, that
2155     // all internal references have been released.
2156     // Unfortunately, certain CordbBase objects are unrooted and thus we have no
2157     // good time to neuter them and clean up any internal references they may hold.
2158     // So we keep count of those guys too.
2159     static LONG s_DbgMemTotalOutstandingCordb;
2160     static LONG s_DbgMemTotalOutstandingInternalRefs;
2161 #endif
2162
2163     //
2164     // Turn this on to enable an array which will contain all objects that have
2165     // not been completely released.
2166     //
2167     // #define TRACK_OUTSTANDING_OBJECTS 1
2168
2169 #ifdef TRACK_OUTSTANDING_OBJECTS
2170
2171 #define MAX_TRACKED_OUTSTANDING_OBJECTS 256
2172     static void *Cordb::s_DbgMemOutstandingObjects[MAX_TRACKED_OUTSTANDING_OBJECTS];
2173     static LONG Cordb::s_DbgMemOutstandingObjectMax;
2174 #endif
2175
2176
2177     //-----------------------------------------------------------
2178     // IUnknown
2179     //-----------------------------------------------------------
2180
2181     ULONG STDMETHODCALLTYPE AddRef()
2182     {
2183         return (BaseAddRef());
2184     }
2185     ULONG STDMETHODCALLTYPE Release()
2186     {
2187         return (BaseRelease());
2188     }
2189     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
2190
2191     //-----------------------------------------------------------
2192     // ICorDebug
2193     //-----------------------------------------------------------
2194
2195 #ifdef FEATURE_CORECLR
2196     HRESULT SetTargetCLR(HMODULE hmodTargetCLR);
2197 #endif // FEATURE_CORECLR
2198
2199     COM_METHOD Initialize();
2200     COM_METHOD Terminate();
2201     COM_METHOD SetManagedHandler(ICorDebugManagedCallback *pCallback);
2202     COM_METHOD SetUnmanagedHandler(ICorDebugUnmanagedCallback *pCallback);
2203     COM_METHOD CreateProcess(LPCWSTR lpApplicationName,
2204                              __in_z LPWSTR lpCommandLine,
2205                              LPSECURITY_ATTRIBUTES lpProcessAttributes,
2206                              LPSECURITY_ATTRIBUTES lpThreadAttributes,
2207                              BOOL bInheritHandles,
2208                              DWORD dwCreationFlags,
2209                              PVOID lpEnvironment,
2210                              LPCWSTR lpCurrentDirectory,
2211                              LPSTARTUPINFOW lpStartupInfo,
2212                              LPPROCESS_INFORMATION lpProcessInformation,
2213                              CorDebugCreateProcessFlags debuggingFlags,
2214                              ICorDebugProcess **ppProcess);
2215     COM_METHOD DebugActiveProcess(DWORD dwProcessId, BOOL fWin32Attach, ICorDebugProcess **ppProcess);
2216     COM_METHOD EnumerateProcesses(ICorDebugProcessEnum **ppProcess);
2217     COM_METHOD GetProcess(DWORD dwProcessId, ICorDebugProcess **ppProcess);
2218     COM_METHOD CanLaunchOrAttach(DWORD dwProcessId, BOOL win32DebuggingEnabled);
2219
2220     //-----------------------------------------------------------
2221     // CorDebug
2222     //-----------------------------------------------------------
2223
2224     static COM_METHOD CreateObjectV1(REFIID id, void **object);
2225 #if defined(FEATURE_DBGIPC_TRANSPORT_DI)
2226     static COM_METHOD CreateObjectTelesto(REFIID id, void ** pObject);
2227 #endif // FEATURE_DBGIPC_TRANSPORT_DI
2228     static COM_METHOD CreateObject(CorDebugInterfaceVersion iDebuggerVersion, REFIID id, void **object);
2229
2230     //-----------------------------------------------------------
2231     // ICorDebugRemote
2232     //-----------------------------------------------------------
2233
2234     COM_METHOD CreateProcessEx(ICorDebugRemoteTarget * pRemoteTarget,
2235                                LPCWSTR lpApplicationName,
2236                                __in_z LPWSTR lpCommandLine,
2237                                LPSECURITY_ATTRIBUTES lpProcessAttributes,
2238                                LPSECURITY_ATTRIBUTES lpThreadAttributes,
2239                                BOOL bInheritHandles,
2240                                DWORD dwCreationFlags,
2241                                PVOID lpEnvironment,
2242                                LPCWSTR lpCurrentDirectory,
2243                                LPSTARTUPINFOW lpStartupInfo,
2244                                LPPROCESS_INFORMATION lpProcessInformation,
2245                                CorDebugCreateProcessFlags debuggingFlags,
2246                                ICorDebugProcess ** ppProcess);
2247     
2248     COM_METHOD DebugActiveProcessEx(ICorDebugRemoteTarget * pRemoteTarget, 
2249                                     DWORD dwProcessId, 
2250                                     BOOL fWin32Attach, 
2251                                     ICorDebugProcess ** ppProcess);
2252     
2253
2254     //-----------------------------------------------------------
2255     // Methods not exposed via a COM interface.
2256     //-----------------------------------------------------------
2257
2258     HRESULT CreateProcessCommon(ICorDebugRemoteTarget * pRemoteTarget,
2259                                 LPCWSTR lpApplicationName,
2260                                 __in_z LPWSTR lpCommandLine,
2261                                 LPSECURITY_ATTRIBUTES lpProcessAttributes,
2262                                 LPSECURITY_ATTRIBUTES lpThreadAttributes,
2263                                 BOOL bInheritHandles,
2264                                 DWORD dwCreationFlags,
2265                                 PVOID lpEnvironment,
2266                                 LPCWSTR lpCurrentDirectory,
2267                                 LPSTARTUPINFOW lpStartupInfo,
2268                                 LPPROCESS_INFORMATION lpProcessInformation,
2269                                 CorDebugCreateProcessFlags debuggingFlags,
2270                                 ICorDebugProcess **ppProcess);
2271
2272     HRESULT DebugActiveProcessCommon(ICorDebugRemoteTarget * pRemoteTarget, DWORD id, BOOL win32Attach, ICorDebugProcess **ppProcess);
2273
2274     void EnsureCanLaunchOrAttach(BOOL fWin32DebuggingEnabled);
2275
2276     void EnsureAllowAnotherProcess();
2277     void AddProcess(CordbProcess* process);
2278     void RemoveProcess(CordbProcess* process);
2279     CordbSafeHashTable<CordbProcess> *GetProcessList();
2280
2281     void LockProcessList();
2282     void UnlockProcessList();
2283
2284     #ifdef _DEBUG
2285     bool ThreadHasProcessListLock();
2286     #endif
2287
2288
2289     HRESULT SendIPCEvent(CordbProcess * pProcess,
2290                          DebuggerIPCEvent * pEvent,
2291                          SIZE_T eventSize);
2292
2293     void ProcessStateChanged();
2294
2295     HRESULT WaitForIPCEventFromProcess(CordbProcess* process,
2296                                        CordbAppDomain *appDomain,
2297                                        DebuggerIPCEvent* event);
2298
2299     //-----------------------------------------------------------
2300     // Data members
2301     //-----------------------------------------------------------
2302
2303 public:
2304     RSExtSmartPtr<ICorDebugManagedCallback>    m_managedCallback;
2305     RSExtSmartPtr<ICorDebugManagedCallback2>   m_managedCallback2;
2306     RSExtSmartPtr<ICorDebugManagedCallback3>   m_managedCallback3;
2307     RSExtSmartPtr<ICorDebugUnmanagedCallback>  m_unmanagedCallback;
2308
2309     CordbRCEventThread*         m_rcEventThread;
2310
2311     CorDebugInterfaceVersion    GetDebuggerVersion() const;
2312
2313 #ifdef FEATURE_CORESYSTEM
2314         HMODULE GetTargetCLR() { return m_targetCLR; }
2315 #endif
2316
2317 private:
2318     bool IsCreateProcessSupported();
2319     bool IsInteropDebuggingSupported();
2320     void CheckCompatibility();
2321
2322     CordbSafeHashTable<CordbProcess> m_processes;
2323
2324     // List to track outstanding CordbProcessEnum objects.
2325     NeuterList                  m_pProcessEnumList;
2326
2327     RSLock                      m_processListMutex;
2328     BOOL                        m_initialized;
2329
2330     // This is the version of the ICorDebug APIs that the debugger believes it's consuming.
2331     CorDebugInterfaceVersion    m_debuggerSpecifiedVersion;
2332
2333 //Note - this code could be useful outside coresystem, but keeping the change localized
2334 // because we are late in the win8 release
2335 #ifdef FEATURE_CORESYSTEM
2336         HMODULE m_targetCLR;
2337 #endif
2338 };
2339
2340
2341
2342
2343 /* ------------------------------------------------------------------------- *
2344  * AppDomain class
2345  * ------------------------------------------------------------------------- */
2346
2347 // Provides the implementation for ICorDebugAppDomain, ICorDebugAppDomain2, 
2348 // and ICorDebugAppDomain3
2349 class CordbAppDomain : public CordbBase, 
2350                         public ICorDebugAppDomain, 
2351                         public ICorDebugAppDomain2,
2352                         public ICorDebugAppDomain3,
2353                         public ICorDebugAppDomain4
2354 {
2355 public:
2356     // Create a CordbAppDomain object based on a pointer to the AppDomain instance in the CLR 
2357     CordbAppDomain(CordbProcess *  pProcess,
2358                    VMPTR_AppDomain vmAppDomain);
2359
2360     virtual ~CordbAppDomain();
2361
2362     virtual void Neuter();
2363
2364     using CordbBase::GetProcess;
2365
2366 #ifdef _DEBUG
2367     virtual const char * DbgGetName() { return "CordbAppDomain"; }
2368 #endif
2369
2370
2371     //-----------------------------------------------------------
2372     // IUnknown
2373     //-----------------------------------------------------------
2374
2375     ULONG STDMETHODCALLTYPE AddRef()
2376     {
2377         return (BaseAddRef());
2378     }
2379     ULONG STDMETHODCALLTYPE Release()
2380     {
2381         return (BaseRelease());
2382     }
2383     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
2384
2385     //-----------------------------------------------------------
2386     // ICorDebugController
2387     //-----------------------------------------------------------
2388
2389     COM_METHOD Stop(DWORD dwTimeout);
2390     COM_METHOD Continue(BOOL fIsOutOfBand);
2391     COM_METHOD IsRunning(BOOL * pbRunning);
2392     COM_METHOD HasQueuedCallbacks(ICorDebugThread * pThread, 
2393                                   BOOL *            pbQueued);
2394     COM_METHOD EnumerateThreads(ICorDebugThreadEnum ** ppThreads);
2395     COM_METHOD SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread * pExceptThisThread);
2396     
2397     // Deprecated, returns E_NOTIMPL
2398     COM_METHOD Detach();
2399
2400     COM_METHOD Terminate(unsigned int exitCode);
2401
2402     COM_METHOD CanCommitChanges(
2403         ULONG                              cSnapshots,
2404         ICorDebugEditAndContinueSnapshot * pSnapshots[],
2405         ICorDebugErrorInfoEnum **          pError);
2406
2407     COM_METHOD CommitChanges(
2408         ULONG                              cSnapshots,
2409         ICorDebugEditAndContinueSnapshot * pSnapshots[],
2410         ICorDebugErrorInfoEnum **          pError);
2411
2412     //-----------------------------------------------------------
2413     // ICorDebugAppDomain
2414     //-----------------------------------------------------------
2415     /*
2416      * GetProcess returns the process containing the app domain
2417      */
2418
2419     COM_METHOD GetProcess(ICorDebugProcess ** ppProcess);
2420
2421     /*
2422      * EnumerateAssemblies enumerates all assemblies in the app domain
2423      */
2424
2425     COM_METHOD EnumerateAssemblies(ICorDebugAssemblyEnum ** ppAssemblies);
2426
2427     COM_METHOD GetModuleFromMetaDataInterface(IUnknown *         pIMetaData,
2428                                               ICorDebugModule ** ppModule);
2429     /*
2430      * EnumerateBreakpoints returns an enum of all active breakpoints
2431      * in the app domain.  This includes all types of breakpoints :
2432      * function breakpoints, data breakpoints, etc.
2433      */
2434
2435     COM_METHOD EnumerateBreakpoints(ICorDebugBreakpointEnum ** ppBreakpoints);
2436
2437     /*
2438      * EnumerateSteppers returns an enum of all active steppers in the app domain.
2439      */
2440
2441     COM_METHOD EnumerateSteppers(ICorDebugStepperEnum ** ppSteppers);
2442
2443     // Deprecated, always returns true.
2444     COM_METHOD IsAttached(BOOL * pfAttached);
2445
2446     // Returns the friendly name of the AppDomain
2447     COM_METHOD GetName(ULONG32   cchName,
2448                        ULONG32 * pcchName,
2449                        __out_ecount_part_opt(cchName, *pcchName) WCHAR     szName[]);
2450
2451     /*
2452      * GetObject returns the runtime app domain object.
2453      * Note:   This method is not yet implemented.
2454      */
2455
2456     COM_METHOD GetObject(ICorDebugValue ** ppObject);
2457
2458     // Deprecated, does nothing
2459     COM_METHOD Attach();
2460     COM_METHOD GetID(ULONG32 * pId);
2461
2462     //-----------------------------------------------------------
2463     // ICorDebugAppDomain2 APIs
2464     //-----------------------------------------------------------
2465     COM_METHOD GetArrayOrPointerType(CorElementType   elementType,
2466                                      ULONG32          nRank,
2467                                      ICorDebugType *  pTypeArg,
2468                                      ICorDebugType ** ppResultType);
2469
2470     COM_METHOD GetFunctionPointerType(ULONG32          cTypeArgs,
2471                                       ICorDebugType *  rgpTypeArgs[],
2472                                       ICorDebugType ** ppResultType);
2473
2474     //-----------------------------------------------------------
2475     // ICorDebugAppDomain3 APIs
2476     //-----------------------------------------------------------
2477     COM_METHOD GetCachedWinRTTypesForIIDs(
2478                                             ULONG32               cGuids,
2479                                         GUID                * guids,
2480                                         ICorDebugTypeEnum * * ppTypesEnum);
2481
2482     COM_METHOD GetCachedWinRTTypes(
2483                                                 ICorDebugGuidToTypeEnum * * ppType);
2484
2485     //-----------------------------------------------------------
2486     // ICorDebugAppDomain4
2487     //-----------------------------------------------------------
2488     COM_METHOD GetObjectForCCW(CORDB_ADDRESS ccwPointer, ICorDebugValue **ppManagedObject);
2489
2490     // Get the VMPTR for this appdomain.
2491     VMPTR_AppDomain GetADToken() { return m_vmAppDomain; }
2492
2493     // Given a metadata interface, find the module in this appdomain that matches it.
2494     CordbModule * GetModuleFromMetaDataInterface(IUnknown *pIMetaData);
2495
2496     // Lookup a module from the cache.  Create and to the cache if needed.
2497     CordbModule * LookupOrCreateModule(VMPTR_Module vmModuleToken, VMPTR_DomainFile vmDomainFileToken);
2498     
2499     // Lookup a module from the cache.  Create and to the cache if needed.
2500     CordbModule * LookupOrCreateModule(VMPTR_DomainFile vmDomainFileToken);
2501
2502     // Callback from DAC for module enumeration
2503     static void ModuleEnumerationCallback(VMPTR_DomainFile vmModule, void * pUserData);
2504
2505     // Use DAC to add any modules for this assembly.
2506     void PrepopulateModules();
2507
2508     void InvalidateName() { m_strAppDomainName.Clear(); }
2509
2510 public:
2511     ULONG               m_AppDomainId;
2512
2513     CordbAssembly * LookupOrCreateAssembly(VMPTR_DomainAssembly vmDomainAssembly);
2514     CordbAssembly * LookupOrCreateAssembly(VMPTR_Assembly vmAssembly);
2515     void RemoveAssemblyFromCache(VMPTR_DomainAssembly vmDomainAssembly);
2516     
2517
2518     CordbSafeHashTable<CordbBreakpoint>  m_breakpoints;
2519
2520     // Unique objects that represent the use of some
2521                                          // basic ELEMENT_TYPE's as type parameters.  These
2522                                          // are shared acrosss the entire process.  We could
2523                                          // go and try to find the classes corresponding to these
2524                                          // element types but it seems simpler just to keep
2525                                          // them as special cases.
2526     CordbSafeHashTable<CordbType>        m_sharedtypes;   
2527
2528     CordbAssembly * CacheAssembly(VMPTR_DomainAssembly vmDomainAssembly);
2529     CordbAssembly * CacheAssembly(VMPTR_Assembly vmAssembly);
2530
2531
2532     // Cache of modules in this appdomain. In the VM, modules live in an assembly.
2533     // This cache lives on the appdomain because we generally want to do appdomain (or process)
2534     // wide lookup.
2535     // This is indexed by VMPTR_DomainFile, which has appdomain affinity.
2536     // This is populated by code:CordbAppDomain::LookupOrCreateModule (which may be invoked
2537     // anytime the RS gets hold of a VMPTR), and are removed at the unload event.
2538     CordbSafeHashTable<CordbModule>      m_modules;
2539 private:
2540     // Cache of assemblies in this appdomain. 
2541     // This is indexed by VMPTR_DomainAssembly, which has appdomain affinity.
2542     // This is populated by code:CordbAppDomain::LookupOrCreateAssembly (which may be invoked
2543     // anytime the RS gets hold of a VMPTR), and are removed at the unload event.
2544     CordbSafeHashTable<CordbAssembly>    m_assemblies;
2545
2546     static void AssemblyEnumerationCallback(VMPTR_DomainAssembly vmDomainAssembly, void * pThis);
2547     void PrepopulateAssembliesOrThrow();
2548
2549     // Use DAC to refresh our name
2550     HRESULT RefreshName();
2551
2552     StringCopyHolder    m_strAppDomainName;
2553
2554     NeuterList          m_TypeNeuterList;  // List of types owned by this AppDomain.
2555
2556     // List of Sweepable objects owned by this AppDomain.
2557     // This includes some objects taht hold resources in the left-side (mainly
2558     // as CordbHandleValue, see code:CordbHandleValue::Dispose), as well as:
2559     // - Cordb*Value objects that survive across continues and have appdomain affinity.
2560     LeftSideResourceCleanupList          m_SweepableNeuterList;  
2561
2562     VMPTR_AppDomain     m_vmAppDomain;
2563 public:
2564     // The "Long" exit list is for items that don't get neutered until the appdomain exits.
2565     // The "Sweepable" exit list is for items that may be neuterable sooner than AD exit.
2566     // By splitting out the list, we can just try to sweep the "Sweepable" list and we
2567     // don't waste any time sweeping things on the "Long" list that aren't neuterable anyways.
2568     NeuterList * GetLongExitNeuterList() { return &m_TypeNeuterList; }
2569     LeftSideResourceCleanupList * GetSweepableExitNeuterList() { return &m_SweepableNeuterList; }
2570
2571     void AddToTypeList(CordbBase *pObject);
2572
2573 };
2574
2575
2576 /* ------------------------------------------------------------------------- *
2577  * Assembly class
2578  * ------------------------------------------------------------------------- */
2579
2580 class CordbAssembly : public CordbBase, public ICorDebugAssembly, ICorDebugAssembly2
2581 {
2582 public:
2583     CordbAssembly(CordbAppDomain *      pAppDomain,
2584                   VMPTR_Assembly        vmAssembly,
2585                   VMPTR_DomainAssembly  vmDomainAssembly);
2586     virtual ~CordbAssembly();
2587     virtual void Neuter();
2588
2589     using CordbBase::GetProcess;
2590
2591 #ifdef _DEBUG
2592     virtual const char * DbgGetName() { return "CordbAssembly"; }
2593 #endif
2594
2595
2596     //-----------------------------------------------------------
2597     // IUnknown
2598     //-----------------------------------------------------------
2599
2600     ULONG STDMETHODCALLTYPE AddRef()
2601     {
2602         return (BaseAddRef());
2603     }
2604     ULONG STDMETHODCALLTYPE Release()
2605     {
2606         return (BaseRelease());
2607     }
2608     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
2609
2610     //-----------------------------------------------------------
2611     // ICorDebugAssembly
2612     //-----------------------------------------------------------
2613
2614     /*
2615      * GetProcess returns the process containing the assembly
2616      */
2617     COM_METHOD GetProcess(ICorDebugProcess ** ppProcess);
2618
2619     // Gets the AppDomain containing this assembly
2620     COM_METHOD GetAppDomain(ICorDebugAppDomain ** ppAppDomain);
2621
2622     /*
2623      * EnumerateModules enumerates all modules in the assembly
2624      */
2625     COM_METHOD EnumerateModules(ICorDebugModuleEnum ** ppModules);
2626
2627     /*
2628      * GetCodeBase returns the code base used to load the assembly
2629      */
2630     COM_METHOD GetCodeBase(ULONG32   cchName,
2631                            ULONG32 * pcchName,
2632                            __out_ecount_part_opt(cchName, *pcchName) WCHAR     szName[]);
2633
2634     // returns the filename of the assembly, or "<unknown>" for in-memory assemblies
2635     COM_METHOD GetName(ULONG32   cchName,
2636                        ULONG32 * pcchName,
2637                        __out_ecount_part_opt(cchName, *pcchName) WCHAR     szName[]);
2638
2639
2640     //-----------------------------------------------------------
2641     // ICorDebugAssembly2
2642     //-----------------------------------------------------------
2643
2644     /*
2645      * IsFullyTrusted returns a flag indicating whether the security system 
2646      * has granted the assembly full trust.
2647      */
2648     COM_METHOD IsFullyTrusted(BOOL * pbFullyTrusted);
2649
2650     //-----------------------------------------------------------
2651     // internal accessors
2652     //-----------------------------------------------------------
2653
2654 #ifdef _DEBUG
2655     void DbgAssertAssemblyDeleted();
2656
2657     static void DbgAssertAssemblyDeletedCallback(VMPTR_DomainAssembly vmDomainAssembly, void * pUserData);
2658 #endif // _DEBUG
2659
2660     CordbAppDomain * GetAppDomain()     { return m_pAppDomain; }
2661
2662     VMPTR_DomainAssembly    GetDomainAssemblyPtr() { return m_vmDomainAssembly; }
2663 private:
2664     VMPTR_Assembly          m_vmAssembly;
2665     VMPTR_DomainAssembly    m_vmDomainAssembly;
2666     CordbAppDomain *        m_pAppDomain;
2667
2668     StringCopyHolder        m_strAssemblyFileName;
2669     Optional<BOOL>          m_foptIsFullTrust;
2670 };
2671
2672
2673 //-----------------------------------------------------------------------------
2674 // Describe what to do w/ a win32 debug event
2675 //-----------------------------------------------------------------------------
2676 class Reaction
2677 {
2678 public:
2679     enum Type
2680     {
2681         // Inband events: Dispatch to Cordbg
2682         // safe for stopping the shell and communicating with the runtime
2683         cInband,
2684
2685         // workaround. Inband event, but NewEvent =false
2686         cInband_NotNewEvent,
2687
2688         // This is a debug event that corresponds with getting to the beginning
2689         // of a first chance hijack.
2690         cFirstChanceHijackStarted,
2691
2692         // This is the debug event that corresponds with getting to the end of
2693         // a hijack. To continue we need to restore an unhijacked context
2694         cInbandHijackComplete,
2695
2696         // This is a debug event which corresponds to re-hiting a previous
2697         // IB event after returning from the hijack. Now we have already dispatched it
2698         // so we know how the user wants it to be continued
2699         // Continue immediately with the previously determined 
2700         cInbandExceptionRetrigger,
2701
2702         // This debug event is a breakpoint in unmanaged code that we placed. It will need
2703         // the M2UHandoffHijack to run the in process breakpoint handling code.
2704         cBreakpointRequiringHijack,
2705
2706         // Oob events: Dispatch to Cordbg
2707         // Not safe stopping events. They must be continued immediately.
2708         cOOB,
2709
2710         // CLR internal exception, Continue(not_handled), don't dispatch
2711         // The CLR expects this exception and will deal with it properly.
2712         cCLR,
2713
2714         // Don't dispatch. Continue(DBG_CONTINUE).
2715         // Common for flare.
2716         cIgnore
2717     };
2718
2719     Type GetType() const { return m_type; };
2720
2721 #ifdef _DEBUG
2722     const char * GetReactionName()
2723     {
2724         switch(m_type)
2725         {
2726             case cInband: return "cInband";
2727             case cInband_NotNewEvent: return "cInband_NotNewEvent";
2728             case cInbandHijackComplete: return "cInbandHijackComplete";
2729             case cInbandExceptionRetrigger: return "cInbandExceptionRetrigger";
2730             case cBreakpointRequiringHijack: return "cBreakpointRequiringHijack";
2731             case cOOB: return "cOOB";
2732             case cCLR: return "cCLR";
2733             case cIgnore: return "cIgnore";
2734             default: return "<unknown>";
2735         }
2736     }
2737     int GetLine()
2738     {
2739         return m_line;
2740     }
2741 #endif
2742
2743     Reaction(Type t, int line) : m_type(t) {
2744 #ifdef _DEBUG
2745         m_line = line;
2746
2747         LOG((LF_CORDB, LL_EVERYTHING, "Reaction:%s (determined on line: %d)\n", GetReactionName(), line));
2748 #endif
2749     };
2750
2751     void operator=(const Reaction & other)
2752     {
2753         m_type = other.m_type;
2754 #ifdef _DEBUG
2755         m_line = other.m_line;
2756 #endif
2757     }
2758
2759 protected:
2760     Type m_type;
2761
2762 #ifdef _DEBUG
2763     // Under a debug build, track the line # for where this came from.
2764     int m_line;
2765 #endif
2766 };
2767
2768 // Macro for creating a Reaction.
2769 #define REACTION(type) Reaction(Reaction::type, __LINE__)
2770
2771 // Different forms of Unmanaged Continue
2772 enum EUMContinueType
2773 {
2774     cOobUMContinue,
2775     cInternalUMContinue,
2776     cRealUMContinue
2777 };
2778
2779 /* ------------------------------------------------------------------------- *
2780  * Process class
2781  * ------------------------------------------------------------------------- */
2782
2783
2784 #ifdef _DEBUG
2785 // On debug, we can afford a larger native event queue..
2786 const int DEBUG_EVENTQUEUE_SIZE = 30;
2787 #else
2788 const int DEBUG_EVENTQUEUE_SIZE = 10;
2789 #endif
2790
2791 void DeleteIPCEventHelper(DebuggerIPCEvent *pDel);
2792
2793
2794 // Private interface on CordbProcess that ShimProcess needs to emulate V2 functionality.
2795 // The fact that we need private hooks means that V3 is not sufficiently finished to allow building
2796 // a V2 debugger. This interface should shrink over time (and eventually go away) as the functionality gets exposed
2797 // publicly. 
2798 // CordbProcess calls back into ShimProcess too, so the public surface of code:ShimProcess plus
2799 // the spots in CordbProcess that call them are additional surface area that may need to addressed
2800 // to make the shim public.
2801 class IProcessShimHooks
2802 {
2803 public:
2804     // Get the OS Process ID of the target.
2805     virtual DWORD GetPid() = 0;
2806
2807     // Request a synchronization for attach. 
2808     // This essentially just sends an AsyncBreak to the left-side. Once the target is
2809     // synchronized, the Shim can use inspection to send all the various fake-attach events. 
2810     // 
2811     // Once the shim has a way of requesting a synchronization from out-of-process for an
2812     // arbitrary running target that's not stopped at a managed debug event, we can
2813     // remove this.
2814     virtual void QueueManagedAttachIfNeeded() = 0;
2815
2816     // Hijack a thread at an unhandled exception to allow us to resume executing the target so
2817     // that the helper thread can run and service IPC requests. This is also needed to allow
2818     // func-eval at a 2nd-chance exception
2819     // 
2820     // This will require an architectural change to remove. Either:
2821     // - actions like func-eval / synchronization may call this directly themselves.
2822     // - the CLR's managed Unhandled-exception event is moved out of the native
2823     // unhandled-exception event, thus making native unhandled exceptions uninteresting to ICorDebug.
2824     // - everything is out-of-process, and so the CLR doesn't need to continue after an unhandled
2825     // native exception.
2826     virtual BOOL HijackThreadForUnhandledExceptionIfNeeded(DWORD dwThreadId) = 0;
2827
2828 #ifdef FEATURE_INTEROP_DEBUGGING
2829     // Private hook to do the bulk of the interop-debugging goo. This includes hijacking inband
2830     // events and queueing them so that the helper-thread can run.
2831     // 
2832     // We can remove this once we kill the helper-thread, or after enough functionality is
2833     // out-of-process that the debugger doesn't need the helper thread when stopped at an event. 
2834     virtual void HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEvent) = 0;
2835 #endif // FEATURE_INTEROP_DEBUGGING
2836
2837     // Get the modules in the order that they were loaded. This is needed to send the fake-attach events
2838     // for module load in the right order.
2839     // 
2840     // This can be removed once ICorDebug's enumerations are ordered.
2841     virtual void GetModulesInLoadOrder(
2842         ICorDebugAssembly * pAssembly, 
2843         RSExtSmartPtr<ICorDebugModule>* pModules,
2844         ULONG countModules) = 0;
2845     
2846     // Get the assemblies in the order that they were loaded. This is needed to send the fake-attach events
2847     // for assembly load in the right order.
2848     // 
2849     // This can be removed once ICorDebug's enumerations are ordered.
2850     virtual void GetAssembliesInLoadOrder(
2851         ICorDebugAppDomain * pAppDomain, 
2852         RSExtSmartPtr<ICorDebugAssembly>* pAssemblies,
2853         ULONG countAssemblies) = 0;
2854
2855     // Queue up fake connection events for attach.
2856     // ICorDebug doesn't expose any enumeration for connections, so the shim needs to call into a
2857     // private hook to enumerate them for attach.
2858     virtual void QueueFakeConnectionEvents() = 0;
2859
2860     // This finishes initializing the IPC channel between the LS + RS, which includes duplicating
2861     // some handles and events. 
2862     // 
2863     // This can be removed once the IPC channel is completely gone and all communication goes
2864     // soley through the data-target.
2865     virtual void FinishInitializeIPCChannel() = 0;
2866     
2867     // Called when stopped at a managed debug event to request a synchronization.
2868     // This can be replaced when we expose synchronization from ICorDebug.
2869     // The fact that the debuggee is at a managed debug event greatly simplifies the request here
2870     // (in contrast to QueueManagedAttachIfNeeded). It means that we can just flip a flag from
2871     // out-of-process, and when the debuggee thread resumes, it can check that flag and do the
2872     // synchronization from in-process.
2873     virtual void RequestSyncAtEvent()= 0;
2874     
2875     virtual bool IsThreadSuspendedOrHijacked(ICorDebugThread * pThread) = 0;
2876 };
2877
2878
2879 // entry for the array of connections in EnumerateConnectionsData
2880 struct EnumerateConnectionsEntry
2881 {
2882 public:
2883     StringCopyHolder m_pName;   // name of the connection
2884     DWORD            m_dwID;    // ID of the connection
2885 };
2886
2887 // data structure used in the callback for enumerating connections (code:CordbProcess::QueueFakeConnectionEvents)
2888 struct EnumerateConnectionsData
2889 {
2890 public:
2891     ~EnumerateConnectionsData()
2892     {
2893         if (m_pEntryArray != NULL)
2894         {
2895             delete [] m_pEntryArray;
2896             m_pEntryArray = NULL;
2897         }
2898     }
2899
2900     CordbProcess * m_pThis;                     // the "this" process
2901     EnumerateConnectionsEntry * m_pEntryArray;  // an array of connections to be filled in 
2902     UINT32         m_uIndex;                    // the next entry in the array to be filled
2903 };
2904
2905 // data structure used in the callback for asserting that an appdomain has been deleted
2906 // (code:CordbProcess::DbgAssertAppDomainDeleted)
2907 struct DbgAssertAppDomainDeletedData
2908 {
2909 public:
2910     CordbProcess *  m_pThis;
2911     VMPTR_AppDomain m_vmAppDomainDeleted;
2912 };
2913
2914 class CordbProcess : 
2915     public CordbBase, 
2916     public ICorDebugProcess, 
2917     public ICorDebugProcess2, 
2918     public ICorDebugProcess3, 
2919     public ICorDebugProcess4,
2920     public ICorDebugProcess5,
2921     public ICorDebugProcess7,
2922         public ICorDebugProcess8,
2923     public IDacDbiInterface::IAllocator,
2924     public IDacDbiInterface::IMetaDataLookup,
2925     public IProcessShimHooks
2926 #ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
2927     , public ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly
2928 #endif
2929 {
2930     // Ctor is private. Use OpenVirtualProcess instead. 
2931     CordbProcess(ULONG64 clrInstanceId, IUnknown * pDataTarget, HMODULE hDacModule,  Cordb * pCordb, DWORD dwProcessID, ShimProcess * pShim);
2932
2933 public:    
2934
2935     virtual ~CordbProcess();
2936     virtual void Neuter();
2937
2938     // Neuter left-side resources for all children
2939     void NeuterChildrenLeftSideResources();
2940
2941     // Neuter all of all children, but not the actual process object.
2942     void NeuterChildren();
2943
2944
2945     // The way to instantiate a new CordbProcess object.
2946     // @dbgtodo  managed pipeline - this is not fully active in all scenarios yet.
2947     static HRESULT OpenVirtualProcess(ULONG64 clrInstanceId,
2948                                       IUnknown * pDataTarget, 
2949                                       HMODULE hDacModule,
2950                                       Cordb * pCordb, 
2951                                       DWORD dwProcessID, 
2952                                       ShimProcess * pShim, 
2953                                       CordbProcess ** ppProcess);
2954
2955     // Helper function to determine whether this ICorDebug is compatibile with a debugger
2956     // designed for the specified major version
2957     static bool IsCompatibleWith(DWORD clrMajorVersion);
2958
2959     //-----------------------------------------------------------
2960     // IMetaDataLookup
2961     // -----------------------------------------------------------    
2962     IMDInternalImport * LookupMetaData(VMPTR_PEFile vmPEFile, bool &isILMetaDataForNGENImage);
2963
2964     // Helper functions for LookupMetaData implementation
2965     IMDInternalImport * LookupMetaDataFromDebugger(VMPTR_PEFile vmPEFile,
2966                                                    bool &isILMetaDataForNGENImage,
2967                                                    CordbModule * pModule);
2968
2969     IMDInternalImport * LookupMetaDataFromDebuggerForSingleFile(CordbModule * pModule,
2970                                                                 LPCWSTR pwszImagePath,
2971                                                                 DWORD dwTimeStamp,
2972                                                                 DWORD dwImageSize);
2973
2974
2975     //-----------------------------------------------------------
2976     // IDacDbiInterface::IAllocator 
2977     //-----------------------------------------------------------
2978
2979     void * Alloc(SIZE_T lenBytes);
2980     void Free(void * p);
2981
2982 #ifdef _DEBUG
2983     virtual const char * DbgGetName() { return "CordbProcess"; }
2984 #endif
2985
2986     //-----------------------------------------------------------
2987     // IUnknown
2988     //-----------------------------------------------------------
2989
2990     ULONG STDMETHODCALLTYPE AddRef()
2991     {
2992         return BaseAddRefEnforceExternal();
2993     }
2994     ULONG STDMETHODCALLTYPE Release()
2995     {
2996         return BaseReleaseEnforceExternal();
2997     }
2998     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
2999
3000     //-----------------------------------------------------------
3001     // ICorDebugController
3002     //-----------------------------------------------------------
3003
3004     COM_METHOD Stop(DWORD dwTimeout);
3005     COM_METHOD Deprecated_Continue();
3006     COM_METHOD IsRunning(BOOL *pbRunning);
3007     COM_METHOD HasQueuedCallbacks(ICorDebugThread *pThread, BOOL *pbQueued);
3008     COM_METHOD EnumerateThreads(ICorDebugThreadEnum **ppThreads);
3009     COM_METHOD SetAllThreadsDebugState(CorDebugThreadState state,
3010                                        ICorDebugThread *pExceptThisThread);
3011     COM_METHOD Detach();
3012     COM_METHOD Terminate(unsigned int exitCode);
3013
3014     COM_METHOD CanCommitChanges(
3015         ULONG cSnapshots,
3016         ICorDebugEditAndContinueSnapshot *pSnapshots[],
3017         ICorDebugErrorInfoEnum **pError);
3018
3019     COM_METHOD CommitChanges(
3020         ULONG cSnapshots,
3021         ICorDebugEditAndContinueSnapshot *pSnapshots[],
3022         ICorDebugErrorInfoEnum **pError);
3023
3024     COM_METHOD Continue(BOOL fIsOutOfBand);
3025     COM_METHOD ThreadForFiberCookie(DWORD fiberCookie,
3026                                     ICorDebugThread **ppThread);
3027     COM_METHOD GetHelperThreadID(DWORD *pThreadID);
3028
3029     //-----------------------------------------------------------
3030     // ICorDebugProcess
3031     //-----------------------------------------------------------
3032
3033     COM_METHOD GetID(DWORD *pdwProcessId);
3034     COM_METHOD GetHandle(HANDLE *phProcessHandle);
3035     COM_METHOD EnableSynchronization(BOOL bEnableSynchronization);
3036     COM_METHOD GetThread(DWORD dwThreadId, ICorDebugThread **ppThread);
3037     COM_METHOD EnumerateBreakpoints(ICorDebugBreakpointEnum **ppBreakpoints);
3038     COM_METHOD EnumerateSteppers(ICorDebugStepperEnum **ppSteppers);
3039     COM_METHOD EnumerateObjects(ICorDebugObjectEnum **ppObjects);
3040     COM_METHOD IsTransitionStub(CORDB_ADDRESS address, BOOL *pbTransitionStub);
3041     COM_METHOD EnumerateModules(ICorDebugModuleEnum **ppModules);
3042     COM_METHOD GetModuleFromMetaDataInterface(IUnknown *pIMetaData,
3043                                               ICorDebugModule **ppModule);
3044     COM_METHOD SetStopState(DWORD threadID, CorDebugThreadState state);
3045     COM_METHOD IsOSSuspended(DWORD threadID, BOOL *pbSuspended);
3046     COM_METHOD GetThreadContext(DWORD threadID, ULONG32 contextSize,
3047                                 BYTE context[]);
3048     COM_METHOD SetThreadContext(DWORD threadID, ULONG32 contextSize,
3049                                 BYTE context[]);
3050     COM_METHOD ReadMemory(CORDB_ADDRESS address, DWORD size, BYTE buffer[],
3051                           SIZE_T *read);
3052     COM_METHOD WriteMemory(CORDB_ADDRESS address, DWORD size, BYTE buffer[],
3053                            SIZE_T *written);
3054
3055     COM_METHOD ClearCurrentException(DWORD threadID);
3056
3057     /*
3058      * EnableLogMessages enables/disables sending of log messages to the
3059      * debugger for logging.
3060      */
3061     COM_METHOD EnableLogMessages(BOOL fOnOff);
3062
3063     /*
3064      * ModifyLogSwitch modifies the specified switch's severity level.
3065      */
3066     COM_METHOD ModifyLogSwitch(__in_z WCHAR *pLogSwitchName, LONG lLevel);
3067
3068     COM_METHOD EnumerateAppDomains(ICorDebugAppDomainEnum **ppAppDomains);
3069     COM_METHOD GetObject(ICorDebugValue **ppObject);
3070
3071     //-----------------------------------------------------------
3072     // ICorDebugProcess2
3073     //-----------------------------------------------------------
3074
3075     COM_METHOD GetThreadForTaskID(TASKID taskId, ICorDebugThread2 ** ppThread);
3076     COM_METHOD GetVersion(COR_VERSION* pInfo);
3077
3078     COM_METHOD SetUnmanagedBreakpoint(CORDB_ADDRESS address, ULONG32 bufsize, BYTE buffer[], ULONG32 * bufLen);
3079     COM_METHOD ClearUnmanagedBreakpoint(CORDB_ADDRESS address);
3080     COM_METHOD GetCodeAtAddress(CORDB_ADDRESS address, ICorDebugCode ** pCode, ULONG32 * offset);
3081
3082     COM_METHOD SetDesiredNGENCompilerFlags(DWORD pdwFlags);
3083     COM_METHOD GetDesiredNGENCompilerFlags(DWORD *pdwFlags );
3084
3085     COM_METHOD GetReferenceValueFromGCHandle(UINT_PTR handle, ICorDebugReferenceValue **pOutValue);
3086
3087     //-----------------------------------------------------------
3088     // ICorDebugProcess3
3089     //-----------------------------------------------------------
3090
3091     // enables or disables CustomNotifications of a given type 
3092     COM_METHOD SetEnableCustomNotification(ICorDebugClass * pClass, BOOL fEnable);
3093
3094     //-----------------------------------------------------------
3095     // ICorDebugProcess4
3096     //-----------------------------------------------------------
3097     COM_METHOD Filter(        
3098         const BYTE pRecord[],
3099         DWORD countBytes,
3100         CorDebugRecordFormat format,
3101         DWORD dwFlags, 
3102         DWORD dwThreadId, 
3103         ICorDebugManagedCallback *pCallback,
3104         DWORD * pContinueStatus);
3105
3106     COM_METHOD ProcessStateChanged(CorDebugStateChange eChange);
3107
3108     //-----------------------------------------------------------
3109     // ICorDebugProcess5
3110     //-----------------------------------------------------------
3111     COM_METHOD GetGCHeapInformation(COR_HEAPINFO *pHeapInfo);
3112     COM_METHOD EnumerateHeap(ICorDebugHeapEnum **ppObjects);
3113     COM_METHOD EnumerateHeapRegions(ICorDebugHeapSegmentEnum **ppRegions);
3114     COM_METHOD GetObject(CORDB_ADDRESS addr, ICorDebugObjectValue **pObject);
3115     COM_METHOD EnableNGENPolicy(CorDebugNGENPolicy ePolicy);
3116     COM_METHOD EnumerateGCReferences(BOOL enumerateWeakReferences, ICorDebugGCReferenceEnum **ppEnum);
3117     COM_METHOD EnumerateHandles(CorGCReferenceType types, ICorDebugGCReferenceEnum **ppEnum);
3118     COM_METHOD GetTypeID(CORDB_ADDRESS obj, COR_TYPEID *pId);
3119     COM_METHOD GetTypeForTypeID(COR_TYPEID id, ICorDebugType **ppType);
3120     COM_METHOD GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLayout);
3121     COM_METHOD GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT *pLayout);
3122     COM_METHOD GetTypeFields(COR_TYPEID id, ULONG32 celt, COR_FIELD fields[], ULONG32 *pceltNeeded);
3123
3124     //-----------------------------------------------------------
3125     // ICorDebugProcess7
3126     //-----------------------------------------------------------
3127     COM_METHOD SetWriteableMetadataUpdateMode(WriteableMetadataUpdateMode flags);
3128
3129     //-----------------------------------------------------------
3130     // ICorDebugProcess8
3131     //-----------------------------------------------------------
3132     COM_METHOD EnableExceptionCallbacksOutsideOfMyCode(BOOL enableExceptionsOutsideOfJMC);
3133
3134 #ifdef FEATURE_LEGACYNETCF_DBG_HOST_CONTROL
3135     // ---------------------------------------------------------------
3136     // ICorDebugLegacyNetCFHostCallbackInvoker_PrivateWindowsPhoneOnly
3137     // ---------------------------------------------------------------
3138
3139     COM_METHOD InvokePauseCallback();
3140     COM_METHOD InvokeResumeCallback();
3141
3142 #endif
3143
3144     //-----------------------------------------------------------
3145     // Methods not exposed via a COM interface.
3146     //-----------------------------------------------------------
3147
3148     HRESULT ContinueInternal(BOOL fIsOutOfBand);
3149     HRESULT StopInternal(DWORD dwTimeout, VMPTR_AppDomain pAppDomainToken);
3150
3151     // Sets an unmanaged breakpoint at the target address
3152     HRESULT SetUnmanagedBreakpointInternal(CORDB_ADDRESS address, ULONG32 bufsize, BYTE buffer[], ULONG32 * bufLen);
3153
3154     // Allocate a buffer within the target and return the range. Throws on error.
3155     TargetBuffer GetRemoteBuffer(ULONG cbBuffer); // throws
3156
3157     // Same as above except also copy-in the contents of a RS buffer using WriteProcessMemory
3158     HRESULT GetAndWriteRemoteBuffer(CordbAppDomain *pDomain, unsigned int bufferSize, const void *bufferFrom, void **ppBuffer);
3159
3160     /*
3161      * This will release a previously allocated left side buffer.
3162      * Often they are deallocated by the LS itself.
3163      */
3164     HRESULT ReleaseRemoteBuffer(void **ppBuffer);
3165
3166
3167     void TargetConsistencyCheck(bool fExpression);
3168
3169     // Activate interop-debugging, after the process has initially been Init()
3170     void EnableInteropDebugging();
3171
3172     HRESULT Init();
3173     void DeleteQueuedEvents();
3174     void CleanupHalfBakedLeftSide();
3175     void Terminating(BOOL fDetach);
3176
3177     CordbThread * TryLookupThread(VMPTR_Thread vmThread);
3178     CordbThread * TryLookupOrCreateThreadByVolatileOSId(DWORD dwThreadId);
3179     CordbThread * TryLookupThreadByVolatileOSId(DWORD dwThreadId);
3180     CordbThread * LookupOrCreateThread(VMPTR_Thread vmThread);
3181
3182     void QueueManagedAttachIfNeeded();
3183     void QueueManagedAttachIfNeededWorker();
3184     HRESULT QueueManagedAttach();
3185
3186     void DetachShim();
3187
3188     // Flush for when the process is running.
3189     void FlushProcessRunning();
3190
3191     // Flush all state.
3192     void FlushAll();
3193
3194     BOOL HijackThreadForUnhandledExceptionIfNeeded(DWORD dwThreadId);
3195
3196     // Filter a CLR notification (subset of exceptions).
3197     void FilterClrNotification(
3198         DebuggerIPCEvent * pManagedEvent, 
3199         RSLockHolder * pLockHolder,
3200         ICorDebugManagedCallback * pCallback);
3201
3202     // Wrapper to invoke IClrDataTarget4::ContinueStatusChanged
3203     void ContinueStatusChanged(DWORD dwThreadId, CORDB_CONTINUE_STATUS dwContinueStatus);
3204
3205
3206     // Request a synchronization to occur after a debug event is dispatched.
3207     void RequestSyncAtEvent();    
3208
3209     //
3210     // Basic managed event plumbing
3211     //
3212
3213     // This is called on the first IPC event from the debuggee. It initializes state. 
3214     void FinishInitializeIPCChannel();
3215     void FinishInitializeIPCChannelWorker();
3216
3217     // This is called on each IPC event from the debuggee.
3218     void HandleRCEvent(DebuggerIPCEvent * pManagedEvent, RSLockHolder * pLockHolder, ICorDebugManagedCallback * pCallback);
3219
3220     // Queue the RC event.
3221     void QueueRCEvent(DebuggerIPCEvent * pManagedEvent);
3222
3223     // This marshals a managed debug event from the 
3224     void MarshalManagedEvent(DebuggerIPCEvent * pManagedEvent);
3225
3226     // This copies a managed debug event from the IPC block and to pManagedEvent.
3227     // The event still needs to be marshalled.
3228     void CopyRCEventFromIPCBlock(DebuggerIPCEvent * pManagedEvent);
3229
3230     // This copies a managed debug event out of the Native-Debug event envelope.
3231     // The event still needs to be marshalled.
3232     bool CopyManagedEventFromTarget(const EXCEPTION_RECORD * pRecord, DebuggerIPCEvent * pLocalManagedEvent);
3233
3234     // Helper for Filter() to verify parameters and return a type-safe exception record.
3235     const EXCEPTION_RECORD * ValidateExceptionRecord(
3236         const BYTE pRawRecord[],
3237         DWORD countBytes,
3238         CorDebugRecordFormat format);
3239
3240     // Helper to read a structure from the target.
3241     template<typename T>
3242     HRESULT SafeReadStruct(CORDB_ADDRESS pRemotePtr, T* pLocalBuffer);
3243
3244     // Helper to write a structure into the target.
3245     template<typename T> 
3246     HRESULT SafeWriteStruct(CORDB_ADDRESS pRemotePtr, const T* pLocalBuffer);
3247
3248     // Reads a buffer from the target
3249     HRESULT SafeReadBuffer(TargetBuffer tb, BYTE * pLocalBuffer, BOOL throwOnError = TRUE);
3250
3251     // Writes a buffer to the target
3252     void SafeWriteBuffer(TargetBuffer tb, const BYTE * pLocalBuffer);
3253
3254 #if defined(FEATURE_INTEROP_DEBUGGING)
3255     void DuplicateHandleToLocalProcess(HANDLE * pLocalHandle, RemoteHANDLE * pRemoteHandle);
3256 #endif // FEATURE_INTEROP_DEBUGGING
3257
3258     bool IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThread);
3259
3260     // Helper to get PID internally.
3261     DWORD GetPid();
3262
3263     HRESULT GetRuntimeOffsets();
3264         
3265     // Are we blocked waiting fo ran OOB event to be continue?
3266     bool IsWaitingForOOBEvent()
3267     {
3268 #ifdef FEATURE_INTEROP_DEBUGGING
3269         return m_outOfBandEventQueue != NULL;
3270 #else
3271         // If no interop, then we're never waiting for an OOB event.
3272         return false;
3273 #endif
3274     }
3275
3276     //
3277     // Shim  callbacks to simulate fake attach events. 
3278     // 
3279
3280
3281     // Callback for Shim to get the assemblies in load order 
3282     void GetAssembliesInLoadOrder(
3283         ICorDebugAppDomain * pAppDomain, 
3284         RSExtSmartPtr<ICorDebugAssembly>* pAssemblies,
3285         ULONG countAssemblies);
3286
3287     // Callback for Shim to get the modules in load order 
3288     void GetModulesInLoadOrder(
3289         ICorDebugAssembly * pAssembly, 
3290         RSExtSmartPtr<ICorDebugModule>* pModules,
3291         ULONG countModules);
3292
3293     // Functions to queue fake Connection events on attach.
3294     static void CountConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData);
3295     static void EnumerateConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData);
3296     void QueueFakeConnectionEvents();
3297
3298
3299
3300     void DispatchRCEvent();
3301
3302     // Dispatch a single event via the callbacks.
3303     void RawDispatchEvent(
3304         DebuggerIPCEvent *          pEvent, 
3305         RSLockHolder *              pLockHolder,
3306         ICorDebugManagedCallback *  pCallback1, 
3307         ICorDebugManagedCallback2 * pCallback2,
3308         ICorDebugManagedCallback3 * pCallback3);
3309
3310     void MarkAllThreadsDirty();
3311
3312     bool CheckIfLSExited();
3313
3314     void Lock()
3315     {
3316         // Lock Hierarchy - shouldn't have List lock when taking/release the process lock.
3317
3318         m_processMutex.Lock();
3319         LOG((LF_CORDB, LL_EVERYTHING, "P::Lock enter, this=0x%p\n", this));
3320     }
3321
3322     void Unlock()
3323     {
3324         // Lock Hierarchy - shouldn't have List lock when taking/releasing the process lock.
3325
3326         LOG((LF_CORDB, LL_EVERYTHING, "P::Lock leave, this=0x%p\n", this));
3327         m_processMutex.Unlock();
3328     }
3329
3330 #ifdef _DEBUG
3331     bool ThreadHoldsProcessLock()
3332     {
3333         return m_processMutex.HasLock();
3334     }
3335 #endif
3336
3337     // Expose the process lock.
3338     // This is the main lock in V3.
3339     RSLock * GetProcessLock()
3340     {
3341         return &m_processMutex;
3342     }
3343
3344
3345     // @dbgtodo  synchronization - the SG lock goes away in V3.
3346     // Expose the stop-go lock b/c varios Cordb objects in our process tree may need to take it.
3347     RSLock * GetStopGoLock()
3348     {
3349         return &m_StopGoLock;
3350     }
3351
3352
3353     void UnrecoverableError(HRESULT errorHR,
3354                             unsigned int errorCode,
3355                             const char *errorFile,
3356                             unsigned int errorLine);
3357     HRESULT CheckForUnrecoverableError();
3358     void VerifyControlBlock();
3359
3360     // The implementation of EnumerateThreads without the public API error checks
3361     VOID InternalEnumerateThreads(RSInitHolder<CordbHashTableEnum> * ppThreads);
3362
3363     //-----------------------------------------------------------
3364     // Convenience routines
3365     //-----------------------------------------------------------
3366
3367     // Is it safe to send events to the LS?
3368     bool IsSafeToSendEvents() { return !m_unrecoverableError && !m_terminated && !m_detached; }
3369
3370     bool IsWin32EventThread();
3371
3372     void HandleSyncCompleteRecieved();
3373
3374     // Send a truly asynchronous IPC event.
3375     void SendAsyncIPCEvent(DebuggerIPCEventType t);
3376
3377     HRESULT SendIPCEvent(DebuggerIPCEvent *event, SIZE_T eventSize)
3378     {
3379         // @dbgtodo - eventually remove this when all IPC events are gone.
3380         // In V3 paths, we can't send IPC events.
3381         if (GetShim() == NULL)
3382         {
3383             STRESS_LOG1(LF_CORDB, LL_INFO1000, "!! Can't send IPC event in V3. %s", IPCENames::GetName(event->type));
3384             return E_NOTIMPL;
3385         }
3386         _ASSERTE(m_cordb != NULL);
3387         return (m_cordb->SendIPCEvent(this, event, eventSize));
3388     }
3389
3390     void InitAsyncIPCEvent(DebuggerIPCEvent *ipce,
3391                       DebuggerIPCEventType type,
3392                       VMPTR_AppDomain vmAppDomain)
3393     {
3394         // Async events only allowed for the following:
3395         _ASSERTE(type == DB_IPCE_ATTACHING);
3396
3397         InitIPCEvent(ipce, type, false, vmAppDomain);
3398         ipce->asyncSend = true;
3399     }
3400
3401     void InitIPCEvent(DebuggerIPCEvent *ipce,
3402                       DebuggerIPCEventType type,
3403                       bool twoWay,
3404                       VMPTR_AppDomain vmAppDomain
3405                       )
3406     {
3407         // zero out the event in case we try and use any uninitialized fields
3408         memset( ipce, 0, sizeof(DebuggerIPCEvent) );
3409         
3410         _ASSERTE((!vmAppDomain.IsNull()) ||
3411                  type == DB_IPCE_GET_GCHANDLE_INFO ||
3412                  type == DB_IPCE_ENABLE_LOG_MESSAGES ||
3413                  type == DB_IPCE_MODIFY_LOGSWITCH ||
3414                  type == DB_IPCE_ASYNC_BREAK ||
3415                  type == DB_IPCE_CONTINUE ||
3416                  type == DB_IPCE_GET_BUFFER ||
3417                  type == DB_IPCE_RELEASE_BUFFER ||
3418                  type == DB_IPCE_IS_TRANSITION_STUB ||
3419                  type == DB_IPCE_ATTACHING ||
3420                  type == DB_IPCE_APPLY_CHANGES ||
3421                  type == DB_IPCE_CONTROL_C_EVENT_RESULT ||
3422                  type == DB_IPCE_SET_REFERENCE ||
3423                  type == DB_IPCE_SET_ALL_DEBUG_STATE ||
3424                  type == DB_IPCE_GET_THREAD_FOR_TASKID ||
3425                  type == DB_IPCE_DETACH_FROM_PROCESS ||
3426                  type == DB_IPCE_INTERCEPT_EXCEPTION ||
3427                  type == DB_IPCE_GET_NGEN_COMPILER_FLAGS ||
3428                  type == DB_IPCE_SET_NGEN_COMPILER_FLAGS || 
3429                  type == DB_IPCE_SET_VALUE_CLASS ||
3430                  type == DB_IPCE_NETCF_HOST_CONTROL_PAUSE ||
3431                  type == DB_IPCE_NETCF_HOST_CONTROL_RESUME);
3432
3433         ipce->type = type;
3434         ipce->hr = S_OK;
3435         ipce->processId = 0;
3436         ipce->vmAppDomain = vmAppDomain;
3437         ipce->vmThread = VMPTR_Thread::NullPtr();
3438         ipce->replyRequired = twoWay;
3439         ipce->asyncSend = false;
3440         ipce->next = NULL;
3441     }
3442
3443     // Looks up a previously constructed CordbClass instance without creating. May return NULL if the 
3444     // CordbClass instance doesn't exist.
3445     CordbClass * LookupClass(ICorDebugAppDomain * pAppDomain, VMPTR_DomainFile vmDomainFile, mdTypeDef classToken);
3446
3447     CordbModule * LookupOrCreateModule(VMPTR_DomainFile vmDomainFile);
3448
3449 #ifdef FEATURE_INTEROP_DEBUGGING
3450     CordbUnmanagedThread *GetUnmanagedThread(DWORD dwThreadId)
3451     {
3452         _ASSERTE(ThreadHoldsProcessLock());
3453         return m_unmanagedThreads.GetBase(dwThreadId);
3454     }
3455 #endif // FEATURE_INTEROP_DEBUGGING
3456
3457     /*
3458      * This will cleanup the patch table, releasing memory,etc.
3459      */
3460     void ClearPatchTable();
3461
3462     /*
3463      * This will grab the patch table from the left side & go through
3464      * it to gather info needed for faster access.  If address,size,buffer
3465      * are passed in, while going through the table we'll undo patches
3466      * in buffer at the same time
3467      */
3468     HRESULT RefreshPatchTable(CORDB_ADDRESS address = NULL, SIZE_T size = NULL, BYTE buffer[] = NULL);
3469
3470     // Find if a patch exists at a given address.
3471     HRESULT FindPatchByAddress(CORDB_ADDRESS address, bool *patchFound, bool *patchIsUnmanaged);
3472
3473     enum AB_MODE
3474     {
3475         AB_READ,
3476         AB_WRITE
3477     };
3478
3479     /*
3480      * Once we've called RefreshPatchTable to get the patch table,
3481      * this routine will iterate through the patches & either apply
3482      * or unapply the patches to buffer. AB_READ => Replaces patches
3483      * in buffer with the original opcode, AB_WRTE => replace opcode
3484      * with breakpoint instruction, caller is responsible for
3485      * updating the patchtable back to the left side.
3486      *
3487      * <TODO>@todo Perf Instead of a copy, undo the changes
3488      * Since the 'buffer' arg is an [in] param, we're not supposed to
3489      * change it.  If we do, we'll allocate & copy it to bufferCopy
3490      * (we'll also set *pbUpdatePatchTable to true), otherwise we
3491      * don't manipuldate bufferCopy (so passing a NULL in for
3492      * reading is fine).</TODO>
3493      */
3494     HRESULT AdjustBuffer(CORDB_ADDRESS address,
3495                          SIZE_T size,
3496                          BYTE buffer[],
3497                          BYTE **bufferCopy,
3498                          AB_MODE mode,
3499                          BOOL *pbUpdatePatchTable = NULL);
3500
3501     /*
3502      * AdjustBuffer, above, doesn't actually update the local patch table
3503      * if asked to do a write.  It stores the changes alongside the table,
3504      * and this will cause the changes to be written to the table (for
3505      * a range of left-side addresses
3506      */
3507     void CommitBufferAdjustments(CORDB_ADDRESS start,
3508                                  CORDB_ADDRESS end);
3509
3510     /*
3511      * Clear the stored changes, or they'll sit there until we
3512      * accidentally commit them
3513      */
3514     void ClearBufferAdjustments();
3515
3516
3517
3518
3519     //-----------------------------------------------------------
3520     // Accessors for key synchronization fields.
3521     //-----------------------------------------------------------
3522
3523     // If CAD is NULL, returns true if all appdomains (ie, the entire process)
3524     // is synchronized.  Otherwise, returns true if the specified appdomain is
3525     // synch'd.
3526     bool GetSynchronized();
3527     void SetSynchronized(bool fSynch);
3528
3529     void IncStopCount();
3530     void DecStopCount();
3531
3532     // Gets the exact stop count. You need the Proecss lock for this.
3533     int GetStopCount();
3534
3535     // Just gets whether we're stopped or not (m_stopped > 0).
3536     // You only need the StopGo lock for this.
3537     // This is biases towards returning false.
3538     bool IsStopped();
3539
3540     bool GetSyncCompleteRecv();
3541     void SetSyncCompleteRecv(bool fSyncRecv);
3542
3543
3544     // Cordbg may not always continue during a callback; but we really shouldn't do meaningful
3545     // work after a callback has returned yet before they've called continue. Thus we may need
3546     // to remember some state at the time of dispatch so that we do stuff at continue.
3547     // Only example here is neutering... we'd like to Neuter an object X after the ExitX callback,
3548     // but we can't neuter it until Continue. So remember X when we dispatch, and neuter this at continue.
3549     // Use a smart ptr to keep it alive until we neuter it.
3550
3551     // Add objects to various neuter lists.
3552     // NeuterOnContinue is for all objects that can be neutered once we continue.
3553     // NeuterOnExit is for all objects that can survive continues (but are neutered on process shutdown).
3554     // If an object's external ref count goes to 0, it gets promoted to the NeuterOnContinue list.
3555     void AddToNeuterOnExitList(CordbBase *pObject);
3556     void AddToNeuterOnContinueList(CordbBase *pObject);
3557
3558     NeuterList * GetContinueNeuterList() { return &m_ContinueNeuterList; }
3559     NeuterList * GetExitNeuterList() { return &m_ExitNeuterList; }
3560
3561     void AddToLeftSideResourceCleanupList(CordbBase * pObject); 
3562
3563     // Routines to read and write thread context records between the processes safely.
3564     HRESULT SafeReadThreadContext(LSPTR_CONTEXT pRemoteContext, DT_CONTEXT * pCtx);
3565     HRESULT SafeWriteThreadContext(LSPTR_CONTEXT pRemoteContext, const DT_CONTEXT * pCtx);
3566
3567 #ifdef FEATURE_INTEROP_DEBUGGING
3568     // Record a win32 event for debugging purposes.
3569     void DebugRecordWin32Event(const DEBUG_EVENT * pEvent, CordbUnmanagedThread * pUThread);
3570 #endif // FEATURE_INTEROP_DEBUGGING
3571
3572     //-----------------------------------------------------------
3573     // Interop Helpers
3574     //-----------------------------------------------------------
3575
3576     // Get the DAC interface.
3577     IDacDbiInterface * GetDAC();
3578
3579     // Get the data-target, which provides access to the debuggee.
3580     ICorDebugDataTarget * GetDataTarget();
3581
3582     BOOL IsDacInitialized();
3583     
3584     void ForceDacFlush();
3585
3586
3587 #ifdef FEATURE_INTEROP_DEBUGGING
3588     // Deal with native debug events for the interop-debugging scenario.
3589     void HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEvent);
3590
3591     void ResumeHijackedThreads();
3592
3593     //@todo - We should try to make these all private
3594     CordbUnmanagedThread *HandleUnmanagedCreateThread(DWORD dwThreadId, HANDLE hThread, void *lpThreadLocalBase);
3595
3596     HRESULT ContinueOOB();
3597     void QueueUnmanagedEvent(CordbUnmanagedThread *pUThread, const DEBUG_EVENT *pEvent);
3598     void DequeueUnmanagedEvent(CordbUnmanagedThread *pUThread);
3599     void QueueOOBUnmanagedEvent(CordbUnmanagedThread *pUThread, const DEBUG_EVENT *pEvent);
3600     void DequeueOOBUnmanagedEvent(CordbUnmanagedThread *pUThread);
3601     void DispatchUnmanagedInBandEvent();
3602     void DispatchUnmanagedOOBEvent();
3603     bool ExceptionIsFlare(DWORD exceptionCode, const void *exceptionAddress);
3604
3605     bool IsSpecialStackOverflowCase(CordbUnmanagedThread *pUThread, const DEBUG_EVENT *pEvent);
3606
3607     HRESULT SuspendUnmanagedThreads();
3608     HRESULT ResumeUnmanagedThreads();
3609
3610     HRESULT HijackIBEvent(CordbUnmanagedEvent * pUnmanagedEvent);
3611             
3612     BOOL HasUndispatchedNativeEvents();
3613     BOOL HasUserUncontinuedNativeEvents();
3614 #endif // FEATURE_INTEROP_DEBUGGING
3615
3616     HRESULT StartSyncFromWin32Stop(BOOL * pfAsyncBreakSent);
3617
3618
3619     // For interop attach, we first do native, and then once Cordbg continues from
3620     // the loader-bp, we kick off the managed attach. This field remembers that
3621     // whether we need the managed attach.
3622     // @dbgtodo  managed pipeline - hoist to shim.
3623     bool m_fDoDelayedManagedAttached;
3624
3625
3626
3627     // Table of CordbEval objects that we've sent over to the LS.
3628     // This is synced via the process lock.
3629     RsPtrTable<CordbEval> m_EvalTable;
3630
3631     void PrepopulateThreadsOrThrow();
3632
3633     // Lookup or create an appdomain.
3634     CordbAppDomain * LookupOrCreateAppDomain(VMPTR_AppDomain vmAppDomain);
3635     
3636     // Get the shared app domain.
3637     CordbAppDomain * GetSharedAppDomain();
3638
3639     // Get metadata dispenser.
3640     IMetaDataDispenserEx * GetDispenser();
3641
3642     // Sets a bitfield reflecting the managed debugging state at the time of
3643     // the jit attach.
3644     HRESULT GetAttachStateFlags(CLR_DEBUGGING_PROCESS_FLAGS *pFlags);
3645
3646     HRESULT GetTypeForObject(CORDB_ADDRESS obj, CordbType **ppType, CordbAppDomain **pAppDomain = NULL);
3647
3648     WriteableMetadataUpdateMode GetWriteableMetadataUpdateMode() { return m_writableMetadataUpdateMode; }
3649 private:
3650
3651 #ifdef _DEBUG
3652     // Assert that vmAppDomainDeleted doesn't show up in dac enumerations
3653     void DbgAssertAppDomainDeleted(VMPTR_AppDomain vmAppDomainDeleted);
3654
3655     // Callback helper for DbgAssertAppDomainDeleted.
3656     static void DbgAssertAppDomainDeletedCallback(VMPTR_AppDomain vmAppDomain, void * pUserData);
3657 #endif // _DEBUG
3658
3659     static void ThreadEnumerationCallback(VMPTR_Thread vmThread, void * pUserData);
3660
3661
3662     // Callback for AppDomain enumeration
3663     static void AppDomainEnumerationCallback(VMPTR_AppDomain vmAppDomain, void * pUserData);
3664
3665     // Helper to create a new CordbAppDomain around the vmptr and cache it
3666     CordbAppDomain * CacheAppDomain(VMPTR_AppDomain vmAppDomain);
3667
3668     // Helper to traverse Appdomains in target and build up our cache.
3669     void PrepopulateAppDomainsOrThrow();
3670
3671     
3672     void ProcessFirstLogMessage (DebuggerIPCEvent *event);
3673     void ProcessContinuedLogMessage (DebuggerIPCEvent *event);
3674
3675     void CloseIPCHandles();
3676     void UpdateThreadsForAdUnload( CordbAppDomain* pAppDomain );
3677
3678 #ifdef FEATURE_INTEROP_DEBUGGING
3679     // Each win32 debug event needs to be triaged to get a Reaction.
3680     Reaction TriageBreakpoint(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3681     Reaction TriageSyncComplete();
3682     Reaction Triage1stChanceNonSpecial(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3683     Reaction TriageExcep1stChanceAndInit(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3684     Reaction TriageExcep2ndChanceAndInit(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3685     Reaction TriageWin32DebugEvent(CordbUnmanagedThread * pUnmanagedThread, const DEBUG_EVENT * pEvent);
3686 #endif // FEATURE_INTEROP_DEBUGGING
3687
3688     //-----------------------------------------------------------
3689     // Data members
3690     //-----------------------------------------------------------
3691
3692 public:
3693     RSSmartPtr<Cordb>     m_cordb;
3694
3695 private:
3696     // OS process handle to live process. 
3697     // @dbgtodo - , Move this into the Shim. This should only be needed in the live-process
3698     // case. Get rid of this since it breaks the data-target abstraction.
3699     // For Mac debugging, this handle is of course not the real process handle.  This is just a handle to
3700     // wait on for process termination.
3701     HANDLE                m_handle;
3702
3703 public:
3704     // Wrapper to get the OS process handle. This is unsafe because it breaks the data-target abstraction.
3705     // The only things that need this should be calls to DuplicateHandle, and some shimming work.    
3706     HANDLE  UnsafeGetProcessHandle()
3707     {
3708         return m_handle;
3709     }
3710
3711     // Set when code:CordbProcess::Detach is called.
3712     // Public APIs can check this and return CORDBG_E_PROCESS_DETACHED.
3713     // @dbgtodo  managed pipeline - really could merge this with neuter. 
3714     bool                  m_detached;
3715
3716     // True if we code:CordbProcess::Stop is called before the managed CreateProcess event.
3717     // In this case, m_initialized is false, and we can't send an AsyncBreak event to the LS.
3718     // (since the LS isn't going to send a SyncComplete event back since the CLR isn't loaded/ready).
3719     // @dbgtodo  managed pipeline - move into shim, along with Stop/Continue.
3720     bool                  m_uninitializedStop;
3721
3722
3723     // m_exiting is true if we know the LS is starting to exit (if the
3724     // RS is telling the LS to exit) or if we know the LS has already exited.
3725     bool                  m_exiting;
3726
3727
3728     // m_terminated can only be set to true if we know 100% the LS has exited (ie, somebody
3729     // waited on the LS process handle).
3730     bool                  m_terminated;
3731
3732     bool                  m_unrecoverableError;
3733
3734     bool                  m_specialDeferment;
3735     bool                  m_helperThreadDead; // flag used for interop
3736
3737     // This tracks if the loader breakpoint has been received during interop-debugging.
3738     // The Loader Breakpoint is an breakpoint event raised by the OS once the debugger is attached.
3739     // It comes in both Attach and Launch scenarios.
3740     // This is also used in fake-native debugging scenarios.
3741     bool                  m_loaderBPReceived;
3742
3743
3744 private:
3745
3746     // MetaData dispenser. 
3747     RSExtSmartPtr<IMetaDataDispenserEx> m_pMetaDispenser;
3748
3749     //
3750     // Count of the number of outstanding CordbEvals in the process.
3751     //
3752     LONG                  m_cOutstandingEvals;
3753
3754     // Number of oustanding code:CordbHandleValue objects containing 
3755     // Left-side resources. This can be used to tell if ICorDebug needs to
3756     // cleanup gc handles.
3757     LONG                  m_cOutstandingHandles;
3758
3759     // Pointer to the CordbModule instance that can currently change the Jit flags.
3760     // There can be at most one of these. It will represent a module that has just been loaded, before the
3761     // Continue is sent. See code:CordbProcess::RawDispatchEvent and code:CordbProcess::ContinueInternal.
3762     CordbModule * m_pModuleThatCanChangeJitFlags;
3763
3764 public:
3765     LONG OutstandingEvalCount()
3766     {
3767         return m_cOutstandingEvals;
3768     }
3769
3770     void IncrementOutstandingEvalCount()
3771     {
3772         InterlockedIncrement(&m_cOutstandingEvals);
3773     }
3774
3775     void DecrementOutstandingEvalCount()
3776     {
3777         InterlockedDecrement(&m_cOutstandingEvals);
3778     }
3779
3780     LONG OutstandingHandles();
3781     void IncrementOutstandingHandles();
3782     void DecrementOutstandingHandles();
3783
3784     //
3785     // Is it OK to detach at this time
3786     //
3787     HRESULT IsReadyForDetach();
3788
3789     
3790 private:
3791     // This is a target pointer that uniquely identifies the runtime in the target.
3792     // This lets ICD discriminate between multiple CLRs within a single process.
3793     // On windows, this is the base-address of mscorwks.dll in the target.
3794     // If this is 0, then we have V2 semantics where there was only 1 CLR in the target.
3795     // In that case, we can lazily initialize it in code:CordbProcess::CopyManagedEventFromTarget.
3796     // This is just used for backwards compat.
3797     CORDB_ADDRESS         m_clrInstanceId;
3798
3799     // List of things that get neutered on process exit and Continue respectively.
3800     NeuterList            m_ExitNeuterList;
3801     NeuterList            m_ContinueNeuterList;
3802
3803     // List of objects that hold resources into the left-side.
3804     // This is currently for funceval, which cleans up resources in code:CordbEval::SendCleanup.
3805     // @dbgtodo - , (func-eval feature crew): we can get rid of this
3806     // list if we make func-eval not hold resources after it's complete.
3807     LeftSideResourceCleanupList m_LeftSideResourceCleanupList;
3808
3809     // m_stopCount, m_synchronized, & m_syncCompleteReceived are key fields describing
3810     // the processes' sync status.
3811     DWORD                 m_stopCount;
3812
3813     // m_synchronized is the Debugger's view of SyncStatus. It will go high & low for each
3814     // callback. Continue() will set this to false.
3815     // This flag is true roughly from the time that we've dispatched a managed callback
3816     // until the time that it's continued.
3817     bool                  m_synchronized;
3818
3819     // m_syncCompleteReceived tells us if the runtime is _actually_ sychronized. It goes
3820     // high once we get a SyncComplete, and it goes low once we actually send the continue.
3821     // This is always set by the thread that receives the sync-complete. In interop, that's the w32et.
3822     // Thus this is the most accurate indication of wether the Debuggee is _actually_ synchronized or not.
3823     bool                  m_syncCompleteReceived;
3824
3825
3826     // Back pointer to Shim process. This is used for hooks back into the shim.
3827     // If this is Non-null, then we're emulating the V2 case. If this is NULL, then it's the real V3 pipeline.    
3828     RSExtSmartPtr<ShimProcess> m_pShim;
3829
3830     CordbSafeHashTable<CordbThread>           m_userThreads;
3831
3832 public:
3833     ShimProcess* GetShim();
3834
3835     bool                  m_oddSync;
3836
3837
3838     void BuildThreadEnum(CordbBase * pOwnerObj, NeuterList * pOwnerList, RSInitHolder<CordbHashTableEnum> * pHolder);
3839
3840 #ifdef FEATURE_INTEROP_DEBUGGING    
3841     // List of unmanaged threads. This is only populated for interop-debugging.
3842     CordbSafeHashTable<CordbUnmanagedThread>  m_unmanagedThreads;
3843 #endif // FEATURE_INTEROP_DEBUGGING
3844
3845     CordbSafeHashTable<CordbAppDomain>        m_appDomains;
3846
3847     CordbAppDomain * m_sharedAppDomain;
3848
3849     // Since a stepper can begin in one appdomain, and complete in another,
3850     // we put the hashtable here, rather than on specific appdomains.
3851     CordbSafeHashTable<CordbStepper>          m_steppers;
3852
3853     //  Used to figure out if we have to refresh any reference objects
3854     //  on the left side.  Gets incremented each time a continue is called, or
3855     //  global debugee state is modified in some other way.
3856     UINT                  m_continueCounter;
3857
3858     // Used to track whether the DAC cache has been flushed.
3859     // We use this information to determine whether CordbStackWalk instances need to 
3860     // be refreshed. 
3861     UINT                  m_flushCounter;
3862
3863     // The DCB is essentially a buffer area used to temporarily hold information read from the debugger
3864     // control block residing on the LS helper thread. We make no assumptions about the validity of this
3865     // information over time, so before using a value from it on the RS, we will always update this buffer
3866     // with a call to UpdateRightSideDCB. This uses a ReadProcessMemory to get the current information from
3867     // the LS DCB.
3868     DebuggerIPCControlBlock * GetDCB() {return ((m_pEventChannel == NULL) ? NULL : m_pEventChannel->GetDCB());}
3869
3870
3871     DebuggerIPCRuntimeOffsets m_runtimeOffsets;
3872     HANDLE                    m_leftSideEventAvailable;
3873     HANDLE                    m_leftSideEventRead;
3874 #if defined(FEATURE_INTEROP_DEBUGGING)
3875     HANDLE                    m_leftSideUnmanagedWaitEvent;
3876 #endif // FEATURE_INTEROP_DEBUGGING
3877     
3878
3879     // This becomes true when the RS receives its first managed event.
3880     // This goes false in shutdown cases.
3881     // If this is true, we can assume:
3882     // - the CLR is loaded.
3883     // - the IPC block is opened and initialized.
3884     // - DAC is initialized (see code:CordbProcess::IsDacInitialized) 
3885     //
3886     // If this is false, we can assume:
3887     // - the CLR may not be loaded into the target process.
3888     // - We can't send IPC events to the LS (because we can't expect a response)
3889     //
3890     // Many APIs can check this bit and return CORDBG_E_NOTREADY if it's false. 
3891     bool                  m_initialized;
3892
3893 #ifdef _DEBUG
3894     void * m_pDBGLastIPCEventType;
3895 #endif
3896
3897     bool                  m_stopRequested;
3898     HANDLE                m_stopWaitEvent;
3899     RSLock                m_processMutex;
3900
3901 #ifdef FEATURE_INTEROP_DEBUGGING
3902     // The number of threads which are IsFirstChanceHijacked
3903     DWORD m_cFirstChanceHijackedThreads;
3904
3905     CordbUnmanagedEvent  *m_unmanagedEventQueue;
3906     CordbUnmanagedEvent  *m_lastQueuedUnmanagedEvent;
3907     CordbUnmanagedEvent  *m_lastQueuedOOBEvent;
3908     CordbUnmanagedEvent  *m_outOfBandEventQueue;
3909
3910     CordbUnmanagedEvent  *m_lastDispatchedIBEvent;
3911     bool                  m_dispatchingUnmanagedEvent;
3912     bool                  m_dispatchingOOBEvent;
3913     bool                  m_doRealContinueAfterOOBBlock;
3914
3915     enum
3916     {
3917         PS_WIN32_STOPPED           = 0x0001,
3918         PS_HIJACKS_IN_PLACE        = 0x0002,
3919         PS_SOME_THREADS_SUSPENDED  = 0x0004,
3920         PS_WIN32_ATTACHED          = 0x0008,
3921         PS_WIN32_OUTOFBAND_STOPPED = 0x0010,
3922     };
3923
3924     unsigned int          m_state;
3925 #endif // FEATURE_INTEROP_DEBUGGING
3926
3927     // True if we're interop-debugging, else false.
3928     bool IsInteropDebugging();
3929
3930     DWORD                 m_helperThreadId; // helper thread ID calculated from sniffing from UM thread-create events.
3931
3932     // Is the given thread id a helper thread (real or worker?)
3933     bool IsHelperThreadWorked(DWORD tid);
3934
3935     //
3936     // We cache the LS patch table on the RS.
3937     //
3938
3939     // The array of entries. (The patchtable is a hash implemented as a single-array)
3940     // This array includes empty entries.
3941     // There is an auxillary bucket structure used to map hash codes to array indices.
3942     // We traverse the array, and we recognize an empty slot
3943     // if DebuggerControllerPatch::opcode == 0.
3944     // If we haven't gotten the table, then m_pPatchTable is NULL
3945     BYTE*                 m_pPatchTable;
3946
3947     // The number of entries (both used & unused) in m_pPatchTable.
3948     UINT                  m_cPatch;
3949
3950     // so we know where to write the changes patchtable back to
3951     // This has m_cPatch elements.
3952     BYTE                 *m_rgData;
3953
3954     // Cached value of iNext entries such that:
3955     //      m_rgNextPatch[i] = ((DebuggerControllerPatch*)m_pPatchTable)[i]->iNext;
3956     //      where 0 <= i < m_cPatch
3957     // This provides a linked list (via indices) to traverse the used entries of m_pPatchTable.
3958     // This has m_cPatch elements.
3959     ULONG               *m_rgNextPatch;
3960
3961     // This has m_cPatch elements.
3962     PRD_TYPE             *m_rgUncommitedOpcode;
3963
3964     // CORDB_ADDRESS's are UINT_PTR's (64 bit under _WIN64, 32 bit otherwise)
3965 #if defined(DBG_TARGET_WIN64)
3966 #define MAX_ADDRESS     (_UI64_MAX)
3967 #else
3968 #define MAX_ADDRESS     (ULONG_MAX)
3969 #endif
3970 #define MIN_ADDRESS     (0x0)
3971     CORDB_ADDRESS       m_minPatchAddr; //smallest patch in table
3972     CORDB_ADDRESS       m_maxPatchAddr;
3973
3974     // <TODO>@todo port : if slots of CHashTable change, so should these</TODO>
3975 #define DPT_TERMINATING_INDEX (UINT32_MAX)
3976     // Index into m_pPatchTable of the first patch (first used entry).
3977     ULONG                  m_iFirstPatch;
3978
3979     // Initializes the DAC
3980     void InitDac();
3981
3982     // copy new data from LS DCB to RS buffer
3983     void UpdateRightSideDCB();
3984
3985     // copy new data from RS DCB buffer to LS DCB
3986     void UpdateLeftSideDCBField(void * rsFieldAddr, SIZE_T size);
3987
3988     // allocate and initialize the RS DCB buffer
3989     void GetEventBlock(BOOL * pfBlockExists);
3990
3991     IEventChannel * GetEventChannel();
3992
3993     bool SupportsVersion(CorDebugInterfaceVersion featureVersion);
3994
3995     void StartEventDispatch(DebuggerIPCEventType event);
3996     void FinishEventDispatch();
3997     bool AreDispatchingEvent();
3998
3999     HANDLE GetHelperThreadHandle() { return m_hHelperThread; }
4000
4001     CordbAppDomain* GetDefaultAppDomain() { return m_pDefaultAppDomain; }
4002
4003 #ifdef FEATURE_INTEROP_DEBUGGING    
4004     // Lookup if there's a native BP at the given address. Return NULL not found.
4005     NativePatch * GetNativePatch(const void * pAddress);
4006 #endif // FEATURE_INTEROP_DEBUGGING    
4007
4008     bool  IsBreakOpcodeAtAddress(const void * address);
4009
4010 private:
4011     // 
4012     // handle to helper thread. Used for managed debugging.
4013     // Initialized only after we get the tid from the DCB.
4014     HANDLE m_hHelperThread;
4015
4016     DebuggerIPCEventType  m_dispatchedEvent;   // what event are we currently dispatching?
4017
4018     RSLock            m_StopGoLock;
4019
4020     // Each process has exactly one Default AppDomain
4021     // @dbgtodo  appdomain : We should try and simplify things by removing this.
4022     // At the moment it's necessary for CordbProcess::UpdateThreadsForAdUnload.
4023     CordbAppDomain*     m_pDefaultAppDomain;    // owned by m_appDomains
4024
4025 #ifdef FEATURE_INTEROP_DEBUGGING
4026     // Helpers
4027     CordbUnmanagedThread * GetUnmanagedThreadFromEvent(const DEBUG_EVENT * pEvent);
4028 #endif // FEATURE_INTEROP_DEBUGGING
4029
4030     // Ensure we have a CLR Instance ID to debug
4031     HRESULT EnsureClrInstanceIdSet();
4032
4033 #ifdef FEATURE_INTEROP_DEBUGGING
4034     // // The full debug event is too large, so we just remember the important stuff.
4035     struct MiniDebugEvent
4036     {
4037         BYTE code; // event code from the debug event
4038         CordbUnmanagedThread * pUThread; // unmanaged thread this was on.
4039         // @todo - we should have some misc data.
4040         union
4041         {
4042             struct {
4043                 void * pAddress; // address of an exception
4044                 DWORD dwCode;
4045             } ExceptionData;
4046             struct {
4047                 void * pBaseAddress; // for module load & unload
4048             } ModuleData;
4049         } u;
4050     };
4051
4052     // Group fields that are just used for debug support here.
4053     // Some are included even in retail builds to help debug retail failures.
4054     struct DebugSupport
4055     {
4056         // For debugging, we keep a rolling queue of the last N Win32 debug events.
4057         MiniDebugEvent        m_DebugEventQueue[DEBUG_EVENTQUEUE_SIZE];
4058         int                   m_DebugEventQueueIdx;
4059         int                   m_TotalNativeEvents;
4060
4061         // Breakdown of different types of native events
4062         int                   m_TotalIB;
4063         int                   m_TotalOOB;
4064         int                   m_TotalCLR;
4065     } m_DbgSupport;
4066
4067     CUnorderedArray<NativePatch, 10> m_NativePatchList;
4068 #endif // FEATURE_INTEROP_DEBUGGING
4069
4070     //
4071     // DAC
4072     //
4073
4074     // Try to initalize DAC, may fail
4075     BOOL TryInitializeDac();
4076
4077     // Expect DAC initialize to succeed.
4078     void InitializeDac();
4079
4080     
4081     void CreateDacDbiInterface();
4082     
4083     // Free DAC.
4084     void FreeDac();
4085
4086
4087     HModuleHolder             m_hDacModule;    
4088     RSExtSmartPtr<ICorDebugDataTarget> m_pDACDataTarget;
4089
4090     // The mutable version of the data target, or null if read-only
4091     RSExtSmartPtr<ICorDebugMutableDataTarget> m_pMutableDataTarget;
4092
4093     RSExtSmartPtr<ICorDebugMetaDataLocator>   m_pMetaDataLocator;
4094
4095     IDacDbiInterface *  m_pDacPrimitives;
4096
4097     IEventChannel *     m_pEventChannel;
4098
4099     // If true, then we'll ASSERT if we detect the target is corrupt or inconsistent
4100     // This switch is for diagnostics purposes only and should always be false in retail builds.
4101     bool                m_fAssertOnTargetInconsistency;
4102
4103     // When a successful attempt to read runtime offsets from LS occurs, this flag is set.
4104     bool m_runtimeOffsetsInitialized;
4105
4106     // controls how metadata updated in the target is handled
4107     WriteableMetadataUpdateMode m_writableMetadataUpdateMode;
4108 };
4109
4110 // Some IMDArocess APIs are supported as interop-only.
4111 #define FAIL_IF_MANAGED_ONLY(pProcess) \
4112 { CordbProcess * __Proc = pProcess; if (!__Proc->IsInteropDebugging()) return CORDBG_E_MUST_BE_INTEROP_DEBUGGING; }
4113
4114
4115 /* ------------------------------------------------------------------------- *
4116  * Module class
4117  * ------------------------------------------------------------------------- */
4118
4119 class CordbModule : public CordbBase, 
4120                     public ICorDebugModule, 
4121                     public ICorDebugModule2, 
4122                     public ICorDebugModule3
4123 {
4124 public:
4125     CordbModule(CordbProcess *      process,
4126                 VMPTR_Module        vmModule,
4127                 VMPTR_DomainFile    vmDomainFile);
4128
4129     virtual ~CordbModule();
4130     virtual void Neuter();
4131
4132     using CordbBase::GetProcess;
4133
4134 #ifdef _DEBUG
4135     virtual const char * DbgGetName() { return "CordbModule"; }
4136 #endif
4137
4138
4139     //-----------------------------------------------------------
4140     // IUnknown
4141     //-----------------------------------------------------------
4142
4143     ULONG STDMETHODCALLTYPE AddRef()
4144     {
4145         return (BaseAddRef());
4146     }
4147     ULONG STDMETHODCALLTYPE Release()
4148     {
4149         return (BaseRelease());
4150     }
4151     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
4152
4153     //-----------------------------------------------------------
4154     // ICorDebugModule
4155     //-----------------------------------------------------------
4156
4157     COM_METHOD GetProcess(ICorDebugProcess **ppProcess);
4158     COM_METHOD GetBaseAddress(CORDB_ADDRESS *pAddress);
4159     COM_METHOD GetAssembly(ICorDebugAssembly **ppAssembly);
4160     COM_METHOD GetName(ULONG32 cchName, ULONG32 *pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4161     COM_METHOD EnableJITDebugging(BOOL bTrackJITInfo, BOOL bAllowJitOpts);
4162     COM_METHOD EnableClassLoadCallbacks(BOOL bClassLoadCallbacks);
4163
4164     // Gets the latest version of a function given the methodDef token
4165     COM_METHOD GetFunctionFromToken(mdMethodDef methodDef,
4166                                     ICorDebugFunction **ppFunction);
4167     COM_METHOD GetFunctionFromRVA(CORDB_ADDRESS rva, ICorDebugFunction **ppFunction);
4168     COM_METHOD GetClassFromToken(mdTypeDef typeDef,
4169                                  ICorDebugClass **ppClass);
4170     COM_METHOD CreateBreakpoint(ICorDebugModuleBreakpoint **ppBreakpoint);
4171     
4172     // Not implemented - legacy
4173     COM_METHOD GetEditAndContinueSnapshot(
4174         ICorDebugEditAndContinueSnapshot **ppEditAndContinueSnapshot);
4175
4176     COM_METHOD GetMetaDataInterface(REFIID riid, IUnknown **ppObj);
4177     COM_METHOD GetToken(mdModule *pToken);
4178     COM_METHOD IsDynamic(BOOL *pDynamic);
4179     COM_METHOD GetGlobalVariableValue(mdFieldDef fieldDef,
4180                                    ICorDebugValue **ppValue);
4181     COM_METHOD GetSize(ULONG32 *pcBytes);
4182     COM_METHOD IsInMemory(BOOL *pInMemory);
4183
4184     //-----------------------------------------------------------
4185     // ICorDebugModule2
4186     //-----------------------------------------------------------
4187     COM_METHOD SetJMCStatus(
4188         BOOL fIsUserCode,
4189         ULONG32 cOthers,
4190         mdToken others[]);
4191
4192     // Applies an EnC edit to the module
4193     COM_METHOD ApplyChanges(
4194         ULONG  cbMetaData,
4195         BYTE   pbMetaData[],
4196         ULONG  cbIL,
4197         BYTE   pbIL[]);
4198
4199     // Resolve an assembly given an AssemblyRef token. Note that
4200     // this will not trigger the loading of assembly. If assembly is not yet loaded,
4201     // this will return an CORDBG_E_CANNOT_RESOLVE_ASSEMBLY error
4202     COM_METHOD ResolveAssembly(mdToken tkAssemblyRef,
4203                                    ICorDebugAssembly **ppAssembly);
4204
4205     // Sets EnC and optimization flags
4206     COM_METHOD SetJITCompilerFlags(DWORD dwFlags);
4207
4208     // Gets EnC and optimization flags
4209     COM_METHOD GetJITCompilerFlags(DWORD *pdwFlags);
4210
4211     //-----------------------------------------------------------
4212     // ICorDebugModule3
4213     //-----------------------------------------------------------
4214     COM_METHOD CreateReaderForInMemorySymbols(REFIID riid,
4215                                               void** ppObj);
4216
4217     //-----------------------------------------------------------
4218     // Internal members
4219     //-----------------------------------------------------------
4220
4221 #ifdef _DEBUG
4222     // Debug helper to ensure that module is no longer discoverable
4223     void DbgAssertModuleDeleted();
4224 #endif // _DEBUG
4225
4226     // Internal help to get the "name" (filename or pretty name) of the module.
4227     HRESULT GetNameWorker(ULONG32 cchName, ULONG32 *pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4228     
4229     // Marks that the module's metadata has become invalid and needs to be refetched.
4230     void RefreshMetaData();
4231
4232     // Cache the current continue counter as the one that the LoadEvent is
4233     // dispatched in.
4234     void SetLoadEventContinueMarker();
4235
4236     // Return CORDBG_E_MUST_BE_IN_LOAD_MODULE if this module is not in its load callback.
4237     HRESULT EnsureModuleIsInLoadCallback();
4238
4239     BOOL IsDynamic();
4240
4241     // Gets the latest version of the function for the methodDef, if any
4242     CordbFunction * LookupFunctionLatestVersion(mdMethodDef methodToken);
4243
4244     // Gets the latest version of the function. Creates a new instance if none exists yet.
4245     CordbFunction* LookupOrCreateFunctionLatestVersion(mdMethodDef funcMetaDataToken);
4246
4247     // Finds or creates a function for the first time (not for use on EnC if function doesn't exist yet)
4248     CordbFunction * LookupOrCreateFunction(mdMethodDef token, SIZE_T enCVersion);
4249
4250     // Creates an CordbFunction instances for the first time (not for use on EnC)
4251     CordbFunction * CreateFunction(mdMethodDef token, SIZE_T enCVersion);
4252
4253     // Creates a CordbFunction object to represent the specified EnC version 
4254     HRESULT UpdateFunction(mdMethodDef token,
4255                            SIZE_T newEnCVersion,
4256                            CordbFunction** ppFunction);
4257
4258     CordbClass* LookupClass(mdTypeDef classToken);
4259     HRESULT LookupOrCreateClass(mdTypeDef classToken, CordbClass** ppClass);
4260     HRESULT CreateClass(mdTypeDef classToken, CordbClass** ppClass);
4261     HRESULT LookupClassByToken(mdTypeDef token, CordbClass **ppClass);
4262     HRESULT ResolveTypeRef(mdTypeRef token, CordbClass **ppClass);
4263     HRESULT ResolveTypeRefOrDef(mdToken token, CordbClass **ppClass);
4264
4265     // Sends the event to the left side to apply the changes to the debugee
4266     HRESULT ApplyChangesInternal(
4267         ULONG cbMetaData,
4268         BYTE pbMetaData[],
4269         ULONG cbIL,
4270         BYTE pbIL[]);
4271
4272     // Pulls new metadata if needed in order to ensure the availability of
4273     // the given token
4274     void UpdateMetaDataCacheIfNeeded(mdToken token);
4275
4276     HRESULT InitPublicMetaDataFromFile(const WCHAR * pszFullPathName, DWORD dwOpenFlags, bool validateFileInfo);
4277
4278     // Creates a CordbNativeCode (if it's not already created) and adds it to the
4279     // hash table of CordbNativeCodes belonging to the module.
4280     CordbNativeCode * LookupOrCreateNativeCode(mdMethodDef methodToken,
4281                                                VMPTR_MethodDesc methodDesc,
4282                                                CORDB_ADDRESS startAddress);
4283
4284 private:
4285     // Set the metadata (both public and internal) for the module.
4286     void InitMetaData(TargetBuffer buffer, BOOL useFileMappingOptimization);
4287
4288     // Checks if the given token is in the cached metadata
4289     BOOL CheckIfTokenInMetaData(mdToken token);
4290
4291     // Update the public metadata given a buffer in the target.
4292     void UpdatePublicMetaDataFromRemote(TargetBuffer bufferRemoteMetaData);
4293
4294     // Initialize just the public metadata by reading from an on-disk module
4295     HRESULT InitPublicMetaDataFromFile();
4296     // Initialize just the public metadata by reading new metadata from the buffer
4297     void InitPublicMetaData(TargetBuffer buffer);
4298
4299     // Rebuild the internal metadata given the public one.
4300     void UpdateInternalMetaData();
4301
4302     // Determines whether the on-disk metadata for this module is usable as the
4303     // current metadata
4304     BOOL IsFileMetaDataValid();
4305
4306     // Helper to copy metadata buffer from the Target to the host.
4307     void CopyRemoteMetaData(TargetBuffer buffer, CoTaskMemHolder<VOID> * pLocalBuffer);
4308
4309
4310     CordbAssembly * ResolveAssemblyInternal(mdToken tkAssemblyRef);
4311
4312     BOOL IsWinMD();
4313
4314     //-----------------------------------------------------------
4315     // Convenience routines
4316     //-----------------------------------------------------------
4317
4318 public:
4319     CordbAppDomain *GetAppDomain()
4320     {
4321         return m_pAppDomain;
4322     }
4323
4324     CordbAssembly * GetCordbAssembly ();
4325
4326     // Get the module filename, or NULL if none.  Throws on error.
4327     const WCHAR * GetModulePath();
4328
4329     const WCHAR * GetNGenImagePath();
4330
4331     const VMPTR_DomainFile GetRuntimeDomainFile ()
4332     {
4333         return m_vmDomainFile;
4334     }
4335     
4336     const VMPTR_Module GetRuntimeModule()
4337     {
4338         return m_vmModule;
4339     }
4340
4341     // Get symbol stream for in-memory modules.
4342     IDacDbiInterface::SymbolFormat GetInMemorySymbolStream(IStream ** ppStream);
4343
4344     // accessor for PE file
4345     VMPTR_PEFile GetPEFile();
4346
4347
4348     IMetaDataImport * GetMetaDataImporter();
4349
4350     // accessor for Internal MetaData importer.
4351     IMDInternalImport * GetInternalMD();
4352
4353     //-----------------------------------------------------------
4354     // Data members
4355     //-----------------------------------------------------------
4356
4357 public:
4358     CordbAssembly*   m_pAssembly;
4359     CordbAppDomain*  m_pAppDomain;
4360     CordbSafeHashTable<CordbClass>    m_classes;
4361
4362     // A collection, indexed by methodDef, of the latest version of functions in this module
4363     // The collection is filled lazily by LookupOrCreateFunction
4364     CordbSafeHashTable<CordbFunction> m_functions;
4365
4366     // The real handle into the VM for a module. This is appdomain aware.
4367     // This is the primary VM counterpart for the CordbModule.
4368     VMPTR_DomainFile m_vmDomainFile;
4369
4370     VMPTR_Module m_vmModule;
4371
4372     DWORD            m_EnCCount;
4373
4374 private:
4375     
4376     enum ILWinMDState
4377     {
4378         Uninitialized,
4379         False,
4380         True
4381     };
4382
4383     // Base Address and size of this module in debuggee's process. Maybe null if unknown.
4384     TargetBuffer m_PEBuffer;
4385
4386     BOOL             m_fDynamic; // Dynamic modules can grow (like Reflection Emit)
4387     BOOL             m_fInMemory; // In memory modules don't have file-backing.
4388     ILWinMDState     m_isIlWinMD; // WinMD modules don't support all metadata interfaces
4389
4390     // Indicates that the module must serialize its metadata in process as part of metadata
4391     // refresh. This is required for modules updated on the fly by the profiler
4392     BOOL             m_fForceMetaDataSerialize;
4393
4394     // Full path to module's image, if any.  Empty if none, NULL if not yet set.
4395     StringCopyHolder m_strModulePath;
4396
4397     // Full path to the ngen file. Empty if not ngenned, NULL if not yet set.
4398     // This isn't exposed publicly, but we may use it internally for loading metadata.
4399     StringCopyHolder m_strNGenImagePath;
4400
4401     // "Global" class for this module. Global functions + vars exist in this class.
4402     RSSmartPtr<CordbClass> m_pClass;
4403
4404     // Handle to PEFile, useful for metadata lookups.
4405     // this should always be non-null.
4406     VMPTR_PEFile    m_vmPEFile;
4407
4408     
4409     // Public metadata importer. This is lazily initialized and accessed from code:GetMetaDataImporter
4410     // This is handed out to debugger clients via code:CordbModule::GetMetaDataInterface
4411     // This is also tightly coupled to the internal metadata importer, m_pInternalMetaDataImport. 
4412     RSExtSmartPtr<IMetaDataImport> m_pIMImport;
4413
4414     // Internal metadata object. This is closely tied to the public metadata object (m_pIMImport).
4415     // They share the same backing storage, but expose different interfaces to that storage.
4416     // Debugger authors and tools use the public interfaces.
4417     // DAC-ized operations in the VM require an IMDInternalImport. 
4418     // The public and internal must be updated together.
4419     // This ultimately gets handed back to DAC via code:CordbProcess::LookupMetaData
4420     RSExtSmartPtr<IMDInternalImport> m_pInternalMetaDataImport;
4421     
4422     // Continue counter of when the module was loaded.
4423     // See code:CordbModule::SetLoadEventContinueMarker for details
4424     UINT m_nLoadEventContinueCounter;
4425
4426     // This is a table of all NativeCode objects in the module indexed
4427     // by start address
4428     // The collection is filled lazily by LookupOrCreateNativeCode
4429     CordbSafeHashTable<CordbNativeCode> m_nativeCodeTable;
4430 };
4431
4432
4433 //-----------------------------------------------------------------------------
4434 // Cordb MDA notification
4435 //-----------------------------------------------------------------------------
4436 class CordbMDA : public CordbBase, public ICorDebugMDA
4437 {
4438 public:
4439     CordbMDA(CordbProcess * pProc, DebuggerMDANotification * pData);
4440     ~CordbMDA();
4441
4442     virtual void Neuter();
4443
4444 #ifdef _DEBUG
4445     virtual const char * DbgGetName() { return "CordbMDA"; }
4446 #endif
4447
4448     //-----------------------------------------------------------
4449     // IUnknown
4450     //-----------------------------------------------------------
4451
4452     ULONG STDMETHODCALLTYPE AddRef()
4453     {
4454         return (BaseAddRefEnforceExternal());
4455     }
4456     ULONG STDMETHODCALLTYPE Release()
4457     {
4458         return (BaseReleaseEnforceExternal());
4459     }
4460     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
4461
4462     //-----------------------------------------------------------
4463     // ICorDebugMDA
4464     //-----------------------------------------------------------
4465
4466     // Get the string for the type of the MDA. Never empty.
4467     // This is a convenient performant alternative to getting the XML stream and extracting
4468     // the type from that based off the schema.
4469     COM_METHOD GetName(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4470
4471     // Get a string description of the MDA. This may be empty (0-length).
4472     COM_METHOD GetDescription(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4473
4474     // Get the full associated XML for the MDA. This may be empty.
4475     // This could be a potentially expensive operation if the xml stream is large.
4476     // See the MDA documentation for the schema for this XML stream.
4477     COM_METHOD GetXML(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
4478
4479     COM_METHOD GetFlags(CorDebugMDAFlags * pFlags);
4480
4481     // Thread that the MDA is fired on. We use the os tid instead of an ICDThread in case an MDA is fired on a
4482     // native thread (or a managed thread that hasn't yet entered managed code and so we don't have a ICDThread
4483     // object for it yet)
4484     COM_METHOD GetOSThreadId(DWORD * pOsTid);
4485
4486 private:
4487     NewArrayHolder<WCHAR> m_szName;
4488     NewArrayHolder<WCHAR> m_szDescription;
4489     NewArrayHolder<WCHAR> m_szXml;
4490
4491     DWORD m_dwOSTID;
4492     CorDebugMDAFlags m_flags;
4493 };
4494
4495
4496
4497 struct CordbHangingField
4498 {
4499     FREEHASHENTRY   entry;
4500     FieldData data;
4501 };
4502
4503 // A hashtable for storing EnC hanging field information
4504 // FieldData.m_fldMetadataToken is the key
4505 class CordbHangingFieldTable : public CHashTableAndData<CNewDataNoThrow>
4506 {
4507   private:
4508
4509     BOOL Cmp(SIZE_T k1, const HASHENTRY *pc2)
4510     {
4511         LIMITED_METHOD_CONTRACT;  
4512         return (ULONG)(UINT_PTR)(k1) != 
4513                (reinterpret_cast<const CordbHangingField *>(pc2))->data.m_fldMetadataToken; 
4514     }
4515
4516     ULONG HASH(mdFieldDef fldToken)
4517     {
4518         LIMITED_METHOD_CONTRACT;  
4519         return fldToken; 
4520     }
4521
4522     SIZE_T KEY(mdFieldDef fldToken)
4523     { 
4524         return (SIZE_T)fldToken; 
4525     }
4526
4527   public:
4528
4529 #ifndef DACCESS_COMPILE
4530
4531     CordbHangingFieldTable() : CHashTableAndData<CNewDataNoThrow>(11)
4532     {
4533         NewInit(11, sizeof(CordbHangingField), 11);
4534     }
4535
4536     FieldData * AddFieldInfo(FieldData * pInfo)
4537     {
4538         _ASSERTE(pInfo != NULL);
4539
4540         CordbHangingField *pEntry = (CordbHangingField *)Add(HASH(pInfo->m_fldMetadataToken));
4541         pEntry->data = *pInfo; // copy everything over
4542
4543         // Return a pointer to the data
4544         return &(pEntry->data);
4545     }
4546
4547     void RemoveFieldInfo(mdFieldDef fldToken)
4548     {
4549         CordbHangingField *entry = (CordbHangingField*)Find(HASH(fldToken), KEY(fldToken));
4550         _ASSERTE(entry != NULL);
4551         Delete(HASH(fldToken), (HASHENTRY*)entry);
4552    }
4553
4554 #endif // #ifndef DACCESS_COMPILE
4555
4556     FieldData * GetFieldInfo(mdFieldDef fldToken)
4557     {
4558         CordbHangingField * entry = (CordbHangingField *)Find(HASH(fldToken), KEY(fldToken));
4559         return (entry!=NULL?&(entry->data):NULL);
4560     }
4561 };
4562
4563
4564 /* ------------------------------------------------------------------------- *
4565  * Instantiation.
4566  *
4567  * This struct stores a set of type parameters.  It is used in
4568  * the heap-allocated data structures CordbType and CordbNativeCode.
4569  *
4570  *   CordbType::m_inst.    Stores the class type parameters if any,
4571  *                         or the solitary array type parameter, or the solitary parameter
4572  *                         to a byref type.
4573  *
4574  *   CordbJITILFrame::m_genericArgs.  Stores exact generic parameters for the generic method frame if available
4575  *                                 Need not be identicial if code is shared between generic instantiations.
4576  *                                 May be inexact if real instantiation has been optimized away off
4577  *                                 the frame (nb this gets reported by the left side)
4578  *  
4579  * This is conceptually an array of Type-parameters, with the split (m_cClassTyPars) between
4580  * where the Type's type-parameters end and the Method's type-parameters begin.
4581  * ------------------------------------------------------------------------- */
4582 class Instantiation
4583 {
4584 public:
4585     // Empty ctor
4586     Instantiation()
4587         : m_cInst(0), m_ppInst(NULL), m_cClassTyPars (0)
4588     { }
4589
4590     // Instantiation for Type. 0 Method type-parameters.
4591     Instantiation(unsigned int _cClassInst, CordbType **_ppClassInst)
4592         : m_cInst(_cClassInst), m_ppInst(_ppClassInst), m_cClassTyPars(_cClassInst)
4593     {LIMITED_METHOD_CONTRACT;  }
4594
4595     // Instantiation for Type + Function.
4596     Instantiation(unsigned int _cInst, CordbType **_ppInst, unsigned int numClassTyPars)
4597         : m_cInst(_cInst), m_ppInst(_ppInst),
4598         m_cClassTyPars (numClassTyPars)
4599     { }
4600
4601     // Copy constructor.
4602     Instantiation(const Instantiation &inst)
4603         : m_cInst(inst.m_cInst), m_ppInst(inst.m_ppInst), m_cClassTyPars (inst.m_cClassTyPars)
4604     { }
4605
4606     // Number of elements in array pointed to by m_ppInst
4607     unsigned int m_cInst;
4608
4609     // Pointer to array of CordbType objects. Length of array is m_cInst.    
4610     // Array is Class Type parameters followed by Function's Type parameters.
4611     // Eg, Instantiation for Class<Foo, Goo>::Func<Bar> would be {Foo, Goo, Bar}. 
4612     // m_cInst = 3, m_cClassTyPars = 2. 
4613     // In contrast, Instantiation for Class::Func<Foo, Goo, Bar> would have same
4614     // array, but m_cClassTyPars = 0.
4615     CordbType **m_ppInst;
4616
4617     // Track the split between Type vs. Method type-params. 
4618     unsigned int m_cClassTyPars;
4619 };
4620
4621 //------------------------------------------------------------------------
4622 // CordbType: replaces the use of signatures.
4623 //
4624 // Left Side & Right Side
4625 // ---------------------------
4626 // CordbTypes may come from either the Right Side (via being built up from
4627 //   ICorDebug), or from the Left-Side (being handed back from LS operations
4628 //   like getting the type from an Object the LS handed back).
4629 // The RightSide CordbType corresponds to a Left-Side TypeHandle.
4630 // CordbTypes are communicated across the LS/RS boundary by marshalling
4631 // to BasicTypeData + ExpandedTypeData IPC events.
4632 // 
4633 //
4634 // Invariants on CordbType
4635 // ---------------------------
4636 //
4637 //   The m_elementType is NEVER ELEMENT_TYPE_VAR or ELEMENT_TYPE_MVAR or ELEMENT_TYPE_GENERICINST
4638 //   CordbTypes are always _ground_ types (fully instantiated generics or non-generic types). If 
4639 //   they represent an instantiated type like List<int> then m_inst will be non-empty.
4640 //   
4641 //
4642 //   !!!! The m_elementType is NEVER ELEMENT_TYPE_VALUETYPE !!!!
4643 //   !!!! To find out if it is a value type call CordbType::IsValueType() !!!!
4644 //
4645 // Where CordbTypes are stored
4646 // ---------------------------
4647 //
4648 // Because we could have a significant number of different instantiations for a given templated type, 
4649 // we need an efficient way to store and retrieve the CordbType instances for these instantiations.
4650 // For this reason, we use a tree-like scheme to hash-cons types. To implement this we use the following
4651 // scheme:
4652 //   - CordbTypes are created for "partially instantiated" types,
4653 //     e.g. CordbTypes exist for "Dict" and "Dict<int>" even if the real
4654 //     type being manipulated by the user is "Dict<int,string>"
4655 //   - Subordinate types (E.g. Dict<int,string> is subordinate to Dict<int>,
4656 //     which is itself subordinate to the type for Dict) get stored
4657 //     in the m_spinetypes hash table of the parent type.
4658 //   - In m_spinetypes the pointers of the CordbTypes themselves
4659 //     are used for the unique ids for entries in the table.
4660 // Note that CordbType instances that are created for "partially instantiated" types 
4661 // are never used for any purpose other than efficient hashing. Specifically, the debugger will
4662 // never have reason to expose a partially instantiated type outside of the hashing algorithm.
4663 //
4664 // CordbTypes have object identity: if 2 CordbTypes represent the same type (in the same AppDomain),
4665 // then they will be the same CordbType instance.
4666 //
4667 // Thus the representation for  "Dict<class String,class Foo, class Foo* >" goes as follows:
4668 //    1. Assume the type Foo is represented by CordbClass *5678x
4669 //    1b. Assume the hashtable m_sharedtypes in the AppDomain maps E_T_STRING to the CordbType *0ABCx
4670 //       Assume m_type in class Foo (i.e. CordbClass *5678x) is the CordbType *0DEFx
4671 //       Assume m_type in class Foo maps E_T_PTR to the CordbType *0647x
4672 //    2. The hash table m_spinetypes in "Dict" maps "0ABCx" to a new CordbType
4673 //       representing Dict<String> (a single type application)
4674 //    3. The hash table m_spinetypes in this new CordbType maps "0DEFx" to a
4675 //        new CordbType representing Dict<class String,class Foo>
4676 //    3. The hash table m_spinetypes in this new CordbType maps "0647" to a
4677 //        new CordbType representing Dict<class String,class Foo, class Foo*>
4678 //
4679 // This lets us reuse the existing hash table scheme to build
4680 // up instantiated types of arbitrary size.
4681 //
4682 // Array types are similar, excpet that they start with a head type
4683 // for the "type constructor", e.g. "_ []" is a type constructor with rank 1
4684 // and m_elementType = ELEMENT_TYPE_SZARRAY.  These head constructors are
4685 // stored in the m_sharedtypes table in the appdomain.  The actual instantiations
4686 // of the array types are then subordinate types to the array constructor type.
4687 //
4688 // Other types are simpler, and have unique objects stored in the m_sharedtypes
4689 // table in the appdomain.  This table is indexed by CORDBTYPE_ID in RsType.cpp
4690 //
4691 //
4692 // Memory Management of CordbTypes
4693 // ---------------------------
4694 // All CordbTypes are ultimately stored off the CordbAppDomain object.
4695 // The most common place is in the AppDomain's neuter-list. 
4696 //
4697 // See definition of ICorDebugType for further invariants on types.
4698 //
4699
4700 class CordbType : public CordbBase, public ICorDebugType
4701 {
4702 public:
4703     CordbType(CordbAppDomain *appdomain, CorElementType ty, unsigned int rank);
4704     CordbType(CordbAppDomain *appdomain, CorElementType ty, CordbClass *c);
4705     CordbType(CordbType *tycon, CordbType *tyarg);
4706     virtual ~CordbType();
4707     virtual void Neuter();
4708
4709 #ifdef _DEBUG
4710     virtual const char * DbgGetName() { return "CordbType"; }
4711 #endif
4712
4713     // If you want to force the init to happen even if we think the class
4714     // is up to date, set fForceInit to TRUE
4715     HRESULT Init(BOOL fForceInit);
4716
4717     //-----------------------------------------------------------
4718     // IUnknown
4719     //-----------------------------------------------------------
4720
4721     ULONG STDMETHODCALLTYPE AddRef();
4722     ULONG STDMETHODCALLTYPE Release();
4723     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
4724
4725     //-----------------------------------------------------------
4726     // ICorDebugType
4727     //-----------------------------------------------------------
4728
4729     COM_METHOD GetType(CorElementType *ty);
4730     COM_METHOD GetClass(ICorDebugClass **ppClass);
4731     COM_METHOD EnumerateTypeParameters(ICorDebugTypeEnum **ppTyParEnum);
4732     COM_METHOD GetFirstTypeParameter(ICorDebugType **ppType);
4733     COM_METHOD GetBase(ICorDebugType **ppType);
4734     COM_METHOD GetStaticFieldValue(mdFieldDef fieldDef,
4735                                    ICorDebugFrame * pFrame,
4736                                    ICorDebugValue ** ppValue);
4737     COM_METHOD GetRank(ULONG32 *pnRank);
4738
4739     //-----------------------------------------------------------
4740     // Non-COM members
4741     //-----------------------------------------------------------
4742
4743     //-----------------------------------------------------------
4744     // Basic constructor operations for the algebra of types.
4745     // These all create unique objects within an AppDomain.
4746     //-----------------------------------------------------------
4747
4748     // This one is used to create simple types, e.g. int32, int64, typedbyref etc.
4749     static HRESULT MkType(CordbAppDomain * pAppDomain, 
4750                           CorElementType elementType, 
4751                           CordbType ** ppResultType);
4752
4753     // This one is used to create array, pointer and byref types
4754     static HRESULT MkType(CordbAppDomain * pAppDomain, 
4755                           CorElementType elementType, 
4756                           ULONG rank, 
4757                           CordbType * pType, 
4758                           CordbType ** ppResultType);
4759
4760     // This one is used to create function pointer types.  et must be ELEMENT_TYPE_FNPTR
4761     static HRESULT MkType(CordbAppDomain * pAppDomain, 
4762                           CorElementType elementType, 
4763                           const Instantiation * pInst, 
4764                           CordbType ** ppResultType);
4765
4766     // This one is used to class and value class types, e.g. "class MyClass" or "class ArrayList<int>"
4767     static HRESULT MkType(CordbAppDomain * pAppDomain, 
4768                           CorElementType elementType, 
4769                           CordbClass * pClass, 
4770                           const Instantiation * pInst, 
4771                           CordbType ** ppResultType);
4772
4773     // Some derived constructors...  Use this one if the type is definitely not
4774     // a paramterized type, e.g. to implement functions on the API where types cannot
4775     // be parameterized.
4776     static HRESULT MkUnparameterizedType(CordbAppDomain *appdomain, CorElementType et, CordbClass *cl, CordbType **ppType);
4777
4778     //-----------------------------------------------------------
4779     // Basic destructor operations over the algebra
4780     //-----------------------------------------------------------
4781     void DestUnaryType(CordbType **pRes) ;
4782     void DestConstructedType(CordbClass **pClass, Instantiation *pInst);
4783     void DestNaryType(Instantiation *pInst);
4784
4785     CorElementType GetElementType() { return m_elementType; }
4786     VMPTR_DomainFile GetDomainFile();
4787     VMPTR_Module GetModule();
4788
4789     // If this is a ptr type, get the CordbType that it points to.
4790     // Eg, for CordbType("Int*"), returns CordbType("Int").
4791     // If not a ptr type, returns null.
4792     // Since it's all internal, no reference counting.
4793     // This is effectively a specialized version of DestUnaryType.
4794     CordbType * GetPointerElementType();
4795
4796
4797     // Create a type from metadata
4798     static HRESULT SigToType(CordbModule * pModule, SigParser * pSigParser, const Instantiation * pInst, CordbType ** ppResultType);
4799
4800     // Create a type from from the data received from the left-side
4801     static HRESULT TypeDataToType(CordbAppDomain *appdomain, DebuggerIPCE_ExpandedTypeData *data, CordbType **pRes);
4802     static HRESULT TypeDataToType(CordbAppDomain *appdomain, DebuggerIPCE_BasicTypeData *data, CordbType **pRes);
4803     static HRESULT InstantiateFromTypeHandle(CordbAppDomain * appdomain, 
4804                                              VMPTR_TypeHandle vmTypeHandle, 
4805                                              CorElementType et, 
4806                                              CordbClass * tycon,   
4807                                              CordbType ** pRes);
4808
4809     // Prepare data to send back to left-side during Init() and FuncEval.  Fail if the the exact
4810     // type data is requested but was not fetched correctly during Init()
4811     HRESULT TypeToBasicTypeData(DebuggerIPCE_BasicTypeData *data);
4812     void TypeToExpandedTypeData(DebuggerIPCE_ExpandedTypeData *data);
4813     void TypeToTypeArgData(DebuggerIPCE_TypeArgData *data);
4814
4815     void CountTypeDataNodes(unsigned int *count);
4816     static void CountTypeDataNodesForInstantiation(unsigned int genericArgsCount, ICorDebugType *genericArgs[], unsigned int *count);
4817     static void GatherTypeData(CordbType *type, DebuggerIPCE_TypeArgData **curr_tyargData);
4818     static void GatherTypeDataForInstantiation(unsigned int genericArgsCount, ICorDebugType *genericArgs[], DebuggerIPCE_TypeArgData **curr_tyargData);
4819
4820     HRESULT GetParentType(CordbClass * baseClass, CordbType ** ppRes);
4821
4822     // These are available after Init() has been called....
4823     HRESULT GetUnboxedObjectSize(ULONG32 *res);
4824     HRESULT GetFieldInfo(mdFieldDef fldToken, FieldData ** ppFieldData);
4825
4826     CordbAppDomain *GetAppDomain() { return m_appdomain; }
4827
4828     bool IsValueType();
4829
4830     // Is this type a GC-root.
4831     bool IsGCRoot();
4832
4833 #ifdef FEATURE_64BIT_ALIGNMENT
4834     // checks if the type requires 8-byte alignment.
4835     // this is not exposed via ICorDebug at present.
4836     HRESULT CordbType::RequiresAlign8(BOOL* isRequired);
4837 #endif
4838
4839     //-----------------------------------------------------------
4840     // Data members
4841     //-----------------------------------------------------------
4842
4843 public:
4844     // Internal representation of the element type. This may not map exactly to the public element type.
4845     // Specifically, m_elementType is NEVER: 
4846     //  ELEMENT_TYPE_VAR, ELEMENT_TYPE_MVAR, ELEMENT_TYPE_GENERICINST, 
4847     //  or ELEMENT_TYPE_VALUETYPE.
4848     // To find out if this CordbType corresponds to a value type (instead of Reference type) call CordbType::IsValueType()
4849     CorElementType                 m_elementType;
4850
4851     // The appdomain that this type lives in. Types (and their type-parameters) are all contained in a single appdomain.
4852     // (alhtough the types may be from different modules).
4853     // This is valid for all CordbType objects, regardless of m_elementType;
4854     CordbAppDomain *               m_appdomain; 
4855
4856     // The matching class for this type.
4857     // Initially only set for E_T_CLASS, lazily computed for E_T_STRING and E_T_OBJECT if needed
4858     CordbClass *                   m_pClass; 
4859
4860     ULONG m_rank; // Only set for E_T_ARRAY etc.
4861
4862     // Array of Type Parameters for this Type.
4863     Instantiation                  m_inst;
4864
4865     // A unique mapping from CordbType objects that are type parameters to CordbType objects.  Each mapping
4866     // represents the use of the containing type as type constructor.  e.g. If the containing type
4867     // is CordbType(CordbClass "List") then the table here will map parameters such as (CordbType(CordbClass "String")) to
4868     // the constructed type CordbType(CordbClass "List", <CordbType(CordbClass "String")>)
4869     // @dbgtodo  synchronization - this is currently protected by the Stop-Go lock. Transition to process-lock.
4870     CordbSafeHashTable<CordbType>  m_spinetypes; 
4871
4872     // Valid after Init(), only for E_T_ARRAY etc.and E_T_CLASS when m_pClass->m_classInfo.m_genericArgsCount > 0.
4873     // m_typeHandleExact is the precise Runtime type handle for this type.
4874     VMPTR_TypeHandle               m_typeHandleExact;
4875
4876     // Valid after Init(), only for E_T_CLASS, and when m_pClass->m_classInfo.m_genericArgsCount > 0.  
4877     // May not be set correctly if m_fieldInfoNeedsInit.
4878     SIZE_T                         m_objectSize;
4879
4880     // DON'T KEEP POINTERS TO ELEMENTS OF m_pFields AROUND!!
4881     // This may be deleted if the class gets EnC'd.
4882     //
4883     // Valid after Init(), only for E_T_CLASS, and when m_pClass->m_classInfo.m_genericArgsCount > 0
4884     // All fields will be valid if we have m_typeHandleExact.
4885     // 
4886     // Only some fields will be valid if we have called Init() but still have m_fieldInfoNeedsInit.
4887     DacDbiArrayList<FieldData>     m_fieldList;
4888
4889     HRESULT ReturnedByValue();
4890
4891 private:
4892     static HRESULT MkTyAppType(CordbAppDomain * pAddDomain, 
4893                                CordbType * pType, 
4894                                const Instantiation * pInst, 
4895                                CordbType ** pResultType);
4896
4897     BOOL                    m_fieldInfoNeedsInit;
4898
4899 private:
4900     HRESULT InitInstantiationTypeHandle(BOOL fForceInit);
4901     HRESULT InitInstantiationFieldInfo(BOOL fForceInit);
4902     HRESULT InitStringOrObjectClass(BOOL fForceInit);
4903 };
4904
4905 /* ------------------------------------------------------------------------- *
4906  * Class class
4907  * ------------------------------------------------------------------------- */
4908
4909 class CordbClass : public CordbBase, public ICorDebugClass, public ICorDebugClass2
4910 {
4911 public:
4912     CordbClass(CordbModule* m, mdTypeDef token);
4913     virtual ~CordbClass();
4914     virtual void Neuter();
4915
4916     using CordbBase::GetProcess;
4917
4918 #ifdef _DEBUG
4919     virtual const char * DbgGetName() { return "CordbClass"; }
4920 #endif
4921
4922
4923     //-----------------------------------------------------------
4924     // IUnknown
4925     //-----------------------------------------------------------
4926
4927     ULONG STDMETHODCALLTYPE AddRef()
4928     {
4929         return (BaseAddRef());
4930     }
4931     ULONG STDMETHODCALLTYPE Release()
4932     {
4933         return (BaseRelease());
4934     }
4935     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
4936
4937     //-----------------------------------------------------------
4938     // ICorDebugClass
4939     //-----------------------------------------------------------
4940
4941     COM_METHOD GetStaticFieldValue(mdFieldDef fieldDef,
4942                                    ICorDebugFrame *pFrame,
4943                                    ICorDebugValue **ppValue);
4944     COM_METHOD GetModule(ICorDebugModule **pModule);
4945     COM_METHOD GetToken(mdTypeDef *pTypeDef);
4946     //-----------------------------------------------------------
4947     // ICorDebugClass2
4948     //-----------------------------------------------------------
4949     COM_METHOD GetParameterizedType(CorElementType elementType,
4950                                     ULONG32 cTypeArgs, 
4951                                     ICorDebugType * rgpTypeArgs[], 
4952                                     ICorDebugType ** ppType);
4953
4954     COM_METHOD SetJMCStatus(BOOL fIsUserCode);
4955
4956     //-----------------------------------------------------------
4957     // Convenience routines and Accessors
4958     //-----------------------------------------------------------
4959
4960     // Helper to get containing module
4961     CordbModule * GetModule()
4962     {
4963         return m_pModule;
4964     }
4965
4966     // get the metadata token for this class
4967     mdTypeDef GetToken() { return m_token; }
4968
4969     // Helper to get the AppDomain the class lives in.
4970     CordbAppDomain * GetAppDomain()
4971     {
4972         return m_pModule->GetAppDomain();
4973     }
4974
4975     // This only very roughly resembles the CLASS_LOAD_LEVEL concept in the VM.
4976     // because DBI's needs are far more coarse grained. Also DBI 
4977     // may contain more, equal, or less information than what is available in
4978     // native runtime data structures. We can have less when we are being lazy
4979     // and haven't yet fetched it. We can have more if use an independent data
4980     // source such as the metadata blob and then compute some type data ourselves
4981     typedef enum 
4982     {
4983         // At this state the constructor has been run. 
4984         // m_module and m_token will be valid
4985         Constructed,
4986
4987         // At this state we have additionally certain to have initialized
4988         // m_fIsValueClass and m_fHasTypeParams
4989         // Calls to IsValueClass() and HasTypeParams() are valid
4990         // This stage should be achievable as long as a runtime type handle
4991         // exists, even if it is unrestored
4992         BasicInfo,
4993
4994         //Everything is loaded, or at least anything created lazily from this
4995         //point on should be certain to succeed (ie m_type)
4996         FullInfo
4997     }
4998     ClassLoadLevel;
4999
5000     ClassLoadLevel GetLoadLevel()
5001     {
5002         return m_loadLevel;
5003     }
5004
5005     // determine if a load event has been sent for this class
5006     BOOL LoadEventSent() { return m_fLoadEventSent; }
5007
5008     // set value of m_fLoadEventSent
5009     void SetLoadEventSent(BOOL fEventSent) { m_fLoadEventSent = fEventSent; }
5010
5011     // determine if the class has been unloaded
5012     BOOL HasBeenUnloaded() { return m_fHasBeenUnloaded; }
5013
5014     // set value of m_fHasBeenUnloaded
5015     void SetHasBeenUnloaded(BOOL fUnloaded) { m_fHasBeenUnloaded = (fUnloaded == TRUE); }
5016
5017     // determine if this is a value class
5018     BOOL IsValueClassNoInit() { return m_fIsValueClass; }
5019
5020     // set value of m_fIsValueClass
5021     void SetIsValueClass(BOOL fIsValueClass) { m_fIsValueClass = (fIsValueClass == TRUE); }
5022
5023     // determine if the value class is known
5024     BOOL IsValueClassKnown() { return m_fIsValueClassKnown; }
5025
5026     // set value of m_fIsValueClassKnown
5027     void SetIsValueClassKnown(BOOL fIsValueClassKnown) { m_fIsValueClassKnown = (fIsValueClassKnown == TRUE); }
5028
5029     // get value of m_type
5030     CordbType * GetType() { return m_type; }
5031
5032     void SetType(CordbType * pType) { m_type.Assign(pType); }
5033
5034     // get the type parameter count
5035     bool HasTypeParams() { _ASSERTE(m_loadLevel >= BasicInfo); return m_fHasTypeParams; }
5036
5037     // get the object size
5038     SIZE_T ObjectSize() { return m_classInfo.m_objectSize; }
5039
5040     // get the metadata token for this class
5041     mdTypeDef MDToken() { return m_token; }
5042
5043     // get the number of fields
5044     unsigned int FieldCount() { return m_classInfo.m_fieldList.Count(); }
5045
5046     //-----------------------------------------------------------
5047     // Functionality shared for CordbType and CordbClass
5048     //-----------------------------------------------------------
5049
5050     static HRESULT SearchFieldInfo(CordbModule *                module,
5051                                    DacDbiArrayList<FieldData> * pFieldList,
5052                                    mdTypeDef                    classToken,
5053                                    mdFieldDef                   fldToken,
5054                                    FieldData **                 ppFieldData);
5055
5056     static HRESULT GetStaticFieldValue2(CordbModule *         pModule,
5057                                         FieldData *           pFieldData,
5058                                         BOOL                  fEnCHangingField,
5059                                         const Instantiation * pInst,
5060                                         ICorDebugFrame *      pFrame, 
5061                                         ICorDebugValue **     ppValue);
5062
5063     //-----------------------------------------------------------
5064     // Non-COM methods
5065     //-----------------------------------------------------------
5066
5067     // Get information about a field that was added by EnC
5068     HRESULT GetEnCHangingField(mdFieldDef         fldToken,
5069                                FieldData **       ppFieldData,
5070                                CordbObjectValue * pObject);
5071
5072 private:
5073     // Get information via the DAC about a field added with Edit and Continue.
5074     FieldData * GetEnCFieldFromDac(BOOL               fStatic,
5075                                    CordbObjectValue * pObject,
5076                                    mdFieldDef         fieldToken);
5077
5078     // Initialize an instance of EnCHangingFieldInfo.
5079     void InitEnCFieldInfo(EnCHangingFieldInfo * pEncField, 
5080                           BOOL                  fStatic,
5081                           CordbObjectValue *    pObject, 
5082                           mdFieldDef            fieldToken, 
5083                           mdTypeDef             classToken);
5084
5085
5086 public:
5087
5088     // set or clear the custom notifications flag to control whether we ignore custom debugger notifications
5089     void SetCustomNotifications(BOOL fEnable) { m_fCustomNotificationsEnabled = fEnable; }
5090     BOOL CustomNotificationsEnabled () { return m_fCustomNotificationsEnabled; }
5091
5092     HRESULT GetFieldInfo(mdFieldDef fldToken, FieldData ** ppFieldData);
5093
5094     // If you want to force the init to happen even if we think the class
5095     // is up to date, set fForceInit to TRUE
5096     void Init(ClassLoadLevel desiredLoadLevel = FullInfo);
5097
5098     // determine if any fields for a type are unallocated statics
5099     BOOL GotUnallocatedStatic(DacDbiArrayList<FieldData> * pFieldList);
5100
5101     bool IsValueClass();
5102     HRESULT GetThisType(const Instantiation * pInst, CordbType ** ppResultType);
5103     static HRESULT PostProcessUnavailableHRESULT(HRESULT hr,
5104                                IMetaDataImport *pImport,
5105                                mdFieldDef fieldDef);
5106     mdTypeDef GetTypeDef() { return (mdTypeDef)m_id; }
5107
5108 #ifdef EnC_SUPPORTED
5109     // when we get an added field or method, mark the class to force re-init when we access it
5110     void MakeOld()
5111     {
5112         m_loadLevel = Constructed;
5113     }
5114 #endif // EnC_SUPPORTED
5115
5116     //-----------------------------------------------------------
5117     // Data members
5118     //-----------------------------------------------------------
5119 private:
5120     // contains information about the type: size and 
5121     // field information
5122     ClassInfo                m_classInfo; 
5123
5124     ClassLoadLevel           m_loadLevel;
5125
5126     // @dbgtodo  managed pipeline - can we get rid of both of these fields?
5127     BOOL                     m_fLoadEventSent;
5128     bool                     m_fHasBeenUnloaded;
5129
5130     // [m_type] is the type object for when this class is used
5131     // as a type.  If the class is a value class then it can represent
5132     // either the boxed or unboxed type - it depends on the context where the
5133     // type is used.  For example on a CordbBoxValue it represents the type of the
5134     // boxed VC, on a CordbVCObjectValue it represents the type of the unboxed VC.
5135     //
5136     // The type field starts of NULL as there
5137     // is no need to create the type object until it is needed.
5138     RSSmartPtr<CordbType>    m_type;
5139
5140     // Module that this Class lives in. Valid at the Constructed type level.
5141     CordbModule *            m_pModule;
5142
5143     // the token for the type constructor - m_id cannot be used for constructed types
5144     // valid at the Constructed type level
5145     mdTypeDef                m_token;  
5146  
5147     // Whether the class is a VC or not is discovered either by
5148     // seeing the class used in a signature after ELEMENT_TYPE_VALUETYPE
5149     // or ELEMENT_TYPE_CLASS or by going and asking the EE.
5150     bool                     m_fIsValueClassKnown;
5151
5152     // Whether the class is a VC or not
5153     bool                     m_fIsValueClass;
5154
5155     // Whether the class has generic type parameters in its definition
5156     bool                     m_fHasTypeParams;
5157
5158     // Timestamp from GetProcess()->m_continueCounter, which we can use to tell if 
5159     // the process has been continued since we last took a snapshot.
5160     UINT                     m_continueCounterLastSync;
5161
5162     // if we add static fields with EnC after this class is loaded (in the debuggee), 
5163     // their value will be hung off the FieldDesc.  Hold information about such fields here.
5164     CordbHangingFieldTable   m_hangingFieldsStatic;
5165
5166     // this indicates whether we should send custom debugger notifications
5167     BOOL                    m_fCustomNotificationsEnabled;
5168
5169 };
5170
5171
5172 /* ------------------------------------------------------------------------- *
5173  * TypeParameter enumerator class
5174  * ------------------------------------------------------------------------- */
5175
5176 class CordbTypeEnum : public CordbBase, public ICorDebugTypeEnum
5177 {
5178 public:
5179     // Factory method: Create a new instance of this class.  Returns NULL on out-of-memory.
5180     // On success, returns a new initialized instance of CordbTypeEnum with ref-count 0 (just like a ctor).
5181     // the life expectancy of the enumerator varies by caller so we require them to specify the applicable neuter list here.
5182     static CordbTypeEnum* Build(CordbAppDomain * pAppDomain, NeuterList * pNeuterList, unsigned int cTypars, CordbType **ppTypars);
5183     static CordbTypeEnum* Build(CordbAppDomain * pAppDomain, NeuterList * pNeuterList, unsigned int cTypars, RSSmartPtr<CordbType>*ppTypars);
5184
5185     virtual ~CordbTypeEnum() ;
5186
5187     virtual void Neuter();
5188
5189
5190 #ifdef _DEBUG
5191     virtual const char * DbgGetName() { return "CordbTypeEnum"; }
5192 #endif
5193
5194
5195     //-----------------------------------------------------------
5196     // IUnknown
5197     //-----------------------------------------------------------
5198
5199     ULONG STDMETHODCALLTYPE AddRef()
5200     {
5201         return (BaseAddRef());
5202     }
5203     ULONG STDMETHODCALLTYPE Release()
5204     {
5205         return (BaseRelease());
5206     }
5207     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5208
5209     //-----------------------------------------------------------
5210     // ICorDebugEnum
5211     //-----------------------------------------------------------
5212
5213     COM_METHOD Skip(ULONG celt);
5214     COM_METHOD Reset();
5215     COM_METHOD Clone(ICorDebugEnum **ppEnum);
5216     COM_METHOD GetCount(ULONG *pcelt);
5217
5218     //-----------------------------------------------------------
5219     // ICorDebugTypeEnum
5220     //-----------------------------------------------------------
5221
5222     COM_METHOD Next(ULONG celt, ICorDebugType *Types[], ULONG *pceltFetched);
5223
5224 private:
5225     // Private constructor, only partially initializes the object.
5226     // Clients should use the 'Build' factory method to create an instance of this class.
5227     CordbTypeEnum( CordbAppDomain * pAppDomain, NeuterList * pNeuterList );
5228     template<class T> static CordbTypeEnum* BuildImpl(CordbAppDomain * pAppDomain, NeuterList * pNeuterList, unsigned int cTypars, T* ppTypars );
5229
5230     // Owning object.
5231     CordbAppDomain * m_pAppDomain;
5232
5233     // Array of Types. We own the array, and share refs to the types.
5234     // @todo- since these are guaranteed to be kept alive as long as we're not neutered,
5235     // we don't need to keep refs to them.
5236     RSSmartPtr<CordbType> * m_ppTypars;
5237     UINT   m_iCurrent;
5238     UINT   m_iMax;
5239 };
5240
5241 /* ------------------------------------------------------------------------- *
5242  * Code enumerator class
5243  * ------------------------------------------------------------------------- */
5244
5245 class CordbCodeEnum : public CordbBase, public ICorDebugCodeEnum
5246 {
5247 public:
5248     CordbCodeEnum(unsigned int cCode, RSSmartPtr<CordbCode> * ppCode);
5249     virtual ~CordbCodeEnum() ;
5250
5251
5252 #ifdef _DEBUG
5253     virtual const char * DbgGetName() { return "CordbCodeEnum"; }
5254 #endif
5255
5256
5257     //-----------------------------------------------------------
5258     // IUnknown
5259     //-----------------------------------------------------------
5260
5261     ULONG STDMETHODCALLTYPE AddRef()
5262     {
5263         return (BaseAddRef());
5264     }
5265     ULONG STDMETHODCALLTYPE Release()
5266     {
5267         return (BaseRelease());
5268     }
5269     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5270
5271     //-----------------------------------------------------------
5272     // ICorDebugEnum
5273     //-----------------------------------------------------------
5274
5275     COM_METHOD Skip(ULONG celt);
5276     COM_METHOD Reset();
5277     COM_METHOD Clone(ICorDebugEnum **ppEnum);
5278     COM_METHOD GetCount(ULONG *pcelt);
5279
5280     //-----------------------------------------------------------
5281     // ICorDebugCodeEnum
5282     //-----------------------------------------------------------
5283
5284     COM_METHOD Next(ULONG celt, ICorDebugCode *Codes[], ULONG *pceltFetched);
5285
5286 private:
5287     // Ptr to an array of CordbCode*
5288     // We own the array.
5289     RSSmartPtr<CordbCode> * m_ppCodes;
5290     UINT   m_iCurrent;
5291     UINT   m_iMax;
5292 };
5293
5294
5295
5296
5297
5298 typedef CUnorderedArray<CordbCode*,11> UnorderedCodeArray;
5299 //<TODO>@todo port: different SIZE_T size/</TODO>
5300 const int DMI_VERSION_INVALID = 0;
5301 const int DMI_VERSION_MOST_RECENTLY_JITTED = 1;
5302 const int DMI_VERSION_MOST_RECENTLY_EnCED = 2;
5303
5304
5305 /* ------------------------------------------------------------------------- *
5306  * Function class
5307  *
5308  * @review .  The CordbFunction class now keeps a multiple MethodDescInfo
5309  * structures in a hash table indexed by tokens provided by the left-side.
5310  * In 99.9% of cases this hash table will only contain one entry - we only
5311  * use a hashtable to cover the case where we have multiple JITtings of
5312  * a single version of a function, in particular multiple JITtings of generic
5313  * code under different instantiations. This will increase space usage.
5314  * The way around it is to store one CordbNativeCode in-line in the CordbFunction
5315  * class, or at least store one such pointer so no hash table will normally
5316  * be needed.  This is similar to other cases, e.g. the hash table in
5317  * CordbClass used to indicate different CordbTypes made from that class -
5318  * again in the normal case these tables will only contain one element.
5319  *
5320  * However, for the moment I've focused on correctness and we can minimize
5321  * this space usage in due course.
5322  * ------------------------------------------------------------------------- */
5323
5324 const BOOL bNativeCode = FALSE;
5325 const BOOL bILCode = TRUE;
5326
5327 //
5328 // Each E&C version gets its own function object. So the IL that a function
5329 // is associated w/ does not change.
5330 // B/C of generics, a single IL function may get jitted multiple times and
5331 // be associated w/ multiple native code blobs (CordbNativeCode).
5332 //
5333 class CordbFunction : public CordbBase, public ICorDebugFunction, public ICorDebugFunction2, public ICorDebugFunction3
5334 {
5335 public:
5336     //-----------------------------------------------------------
5337     // Create from scope and member objects.
5338     //-----------------------------------------------------------
5339     CordbFunction(CordbModule * m,
5340                   mdMethodDef token,
5341                   SIZE_T enCVersion);
5342     virtual ~CordbFunction();
5343     virtual void Neuter();
5344
5345
5346
5347 #ifdef _DEBUG
5348     virtual const char * DbgGetName() { return "CordbFunction"; }
5349 #endif
5350
5351
5352     //-----------------------------------------------------------
5353     // IUnknown
5354     //-----------------------------------------------------------
5355
5356     ULONG STDMETHODCALLTYPE AddRef()
5357     {
5358         return (BaseAddRef());
5359     }
5360     ULONG STDMETHODCALLTYPE Release()
5361     {
5362         return (BaseRelease());
5363     }
5364     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5365
5366     //-----------------------------------------------------------
5367     // ICorDebugFunction
5368     //-----------------------------------------------------------
5369     COM_METHOD GetModule(ICorDebugModule **pModule);
5370     COM_METHOD GetClass(ICorDebugClass **ppClass);
5371     COM_METHOD GetToken(mdMethodDef *pMemberDef);
5372     COM_METHOD GetILCode(ICorDebugCode **ppCode);
5373     COM_METHOD GetNativeCode(ICorDebugCode **ppCode);
5374     COM_METHOD CreateBreakpoint(ICorDebugFunctionBreakpoint **ppBreakpoint);
5375     COM_METHOD GetLocalVarSigToken(mdSignature *pmdSig);
5376     COM_METHOD GetCurrentVersionNumber(ULONG32 *pnCurrentVersion);
5377
5378     //-----------------------------------------------------------
5379     // ICorDebugFunction2
5380     //-----------------------------------------------------------
5381     COM_METHOD SetJMCStatus(BOOL fIsUserCode);
5382     COM_METHOD GetJMCStatus(BOOL * pfIsUserCode);
5383     COM_METHOD EnumerateNativeCode(ICorDebugCodeEnum **ppCodeEnum) { return E_NOTIMPL; }
5384     COM_METHOD GetVersionNumber(ULONG32 *pnCurrentVersion);
5385
5386     //-----------------------------------------------------------
5387     // ICorDebugFunction3
5388     //-----------------------------------------------------------
5389     COM_METHOD GetActiveReJitRequestILCode(ICorDebugILCode **ppReJitedILCode);
5390
5391     //-----------------------------------------------------------
5392     // Internal members
5393     //-----------------------------------------------------------
5394 protected:
5395     // Returns the function's ILCode and SigToken 
5396     HRESULT GetILCodeAndSigToken();
5397
5398     // Get the metadata token for the class to which a function belongs. 
5399     mdTypeDef InitParentClassOfFunctionHelper(mdToken funcMetaDataToken);
5400
5401     // Get information about one of the native code blobs for this function
5402     HRESULT InitNativeCodeInfo();
5403
5404 public:
5405
5406     // Get the class to which a given function belongs
5407     HRESULT InitParentClassOfFunction();
5408
5409     void NotifyCodeCreated(CordbNativeCode* nativeCode);
5410
5411     HRESULT GetSig(SigParser *pMethodSigParser,
5412                    ULONG *pFunctionArgCount,
5413                    BOOL *pFunctionIsStatic);
5414
5415     HRESULT GetArgumentType(DWORD dwIndex, const Instantiation * pInst, CordbType ** ppResultType);
5416
5417
5418     //-----------------------------------------------------------
5419     // Internal routines
5420     //-----------------------------------------------------------
5421
5422     // Get the existing IL code object
5423     HRESULT GetILCode(CordbILCode ** ppCode);
5424
5425     // Finds or creates an ILCode for a given rejit request
5426     HRESULT LookupOrCreateReJitILCode(VMPTR_SharedReJitInfo vmSharedRejitInfo,
5427                                       CordbReJitILCode** ppILCode);
5428
5429
5430 #ifdef EnC_SUPPORTED
5431     void MakeOld();
5432 #endif
5433
5434     //-----------------------------------------------------------
5435     // Accessors
5436     //-----------------------------------------------------------
5437
5438     // Get the AppDomain that this function lives in.
5439     CordbAppDomain * GetAppDomain()
5440     {
5441         return (m_pModule->GetAppDomain());
5442     }
5443
5444     // Get the CordbModule that this Function lives in. 
5445     CordbModule * GetModule()
5446     {
5447         return m_pModule;
5448     }
5449
5450     // Get the CordbClass this of which this function is a member
5451     CordbClass * GetClass()
5452     {
5453         return m_pClass;
5454     }
5455
5456     // Get the IL code blob corresponding to this function
5457     CordbILCode * GetILCode()
5458     {
5459         return m_pILCode;
5460     }
5461
5462     // Get metadata token for this function
5463     mdMethodDef GetMetadataToken()
5464     {
5465         return m_MDToken;
5466     }
5467
5468     SIZE_T GetEnCVersionNumber()
5469     {
5470         return m_dwEnCVersionNumber;
5471     }
5472
5473     CordbFunction * GetPrevVersion()
5474     {
5475         return m_pPrevVersion;
5476     }
5477
5478     void SetPrevVersion(CordbFunction * prevVersion)
5479     {
5480         m_pPrevVersion.Assign(prevVersion);
5481     }
5482
5483     typedef enum {kNativeOnly, kHasIL, kUnknownImpl} ImplementationKind;
5484     ImplementationKind IsNativeImpl()
5485     {
5486         return (m_fIsNativeImpl);
5487     }
5488
5489     // determine whether we have a native-only implementation
5490     void InitNativeImpl();
5491
5492
5493     //-----------------------------------------------------------
5494     // Data members
5495     //-----------------------------------------------------------
5496
5497 private:
5498     // The module that this Function is contained in. It maintains a strong reference to this object
5499     // and will neuter this object.
5500     CordbModule *            m_pModule;
5501
5502     // The Class that this function is contained in. 
5503     CordbClass *             m_pClass;
5504
5505     // We only have 1 IL blob associated with a given Function object.
5506     RSSmartPtr<CordbILCode>  m_pILCode;
5507
5508
5509     // Generics allow a single IL method to be instantiated to multiple native
5510     // code blobs. So CordbFunction : CordbNativeCode is 1:n.
5511     // This pointer is to arbitrary one of those n code bodies.
5512     // Someday we may need to get access to all N of them but not today
5513     RSSmartPtr<CordbNativeCode> m_nativeCode;
5514
5515     // Metadata Token for the IL function. Scoped to m_module.
5516     mdMethodDef              m_MDToken;
5517
5518     // EnC version number of this instance
5519     SIZE_T                   m_dwEnCVersionNumber; 
5520
5521     // link to previous version of this function
5522     RSSmartPtr<CordbFunction> m_pPrevVersion; 
5523
5524     // Is the function implemented natively in the runtime?? (eg, it has no IL, may be an Ecall/fcall)
5525     ImplementationKind       m_fIsNativeImpl; 
5526
5527     // True if method signature (argument) values are cached.
5528     BOOL                     m_fCachedMethodValuesValid;
5529
5530     // Cached SigParser for this Function's argument signature.
5531     // Only valid if m_fCachedMethodValuesValid is set.
5532     SigParser                m_methodSigParserCached;
5533
5534     // Cached Count of arguments in the argument signature.
5535     // Only valid if m_fCachedMethodValuesValid is set.
5536     ULONG                    m_argCountCached;
5537
5538     // Cached boolean if method is static or instance (part of the argument signature).
5539     // Only valid if m_fCachedMethodValuesValid is set.
5540     BOOL                     m_fIsStaticCached;
5541
5542     // A collection, indexed by VMPTR_SharedReJitInfo, of IL code for rejit requests
5543     // The collection is filled lazily by LookupOrCreateReJitILCode
5544     CordbSafeHashTable<CordbReJitILCode> m_reJitILCodes;
5545 };
5546
5547 //-----------------------------------------------------------------------------
5548 // class CordbCode
5549 // Represents either IL or Native code blobs associated with a function.
5550 //
5551 // See the comments at the ICorDebugCode definition for invariants about Code objects.
5552 // 
5553 //-----------------------------------------------------------------------------
5554 class CordbCode : public CordbBase, public ICorDebugCode
5555 {
5556 protected:
5557     CordbCode(CordbFunction * pFunction, UINT_PTR id, SIZE_T encVersion, BOOL fIsIL);
5558
5559 public:
5560     virtual ~CordbCode();
5561     virtual void Neuter();
5562
5563 #ifdef _DEBUG
5564     virtual const char * DbgGetName() = 0;
5565 #endif
5566
5567
5568     //-----------------------------------------------------------
5569     // IUnknown
5570     //-----------------------------------------------------------
5571
5572     ULONG STDMETHODCALLTYPE AddRef()
5573     {
5574         return (BaseAddRef());
5575     }
5576     ULONG STDMETHODCALLTYPE Release()
5577     {
5578         return (BaseRelease());
5579     }
5580     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5581
5582     //-----------------------------------------------------------
5583     // ICorDebugCode
5584     //-----------------------------------------------------------
5585
5586     COM_METHOD IsIL(BOOL * pbIL);
5587     COM_METHOD GetFunction(ICorDebugFunction ** ppFunction);
5588     COM_METHOD GetAddress(CORDB_ADDRESS * pStart) = 0;
5589     COM_METHOD GetSize(ULONG32 * pcBytes);
5590     COM_METHOD CreateBreakpoint(ULONG32 offset,
5591                                 ICorDebugFunctionBreakpoint ** ppBreakpoint);
5592     COM_METHOD GetCode(ULONG32 startOffset, ULONG32 endOffset,
5593                        ULONG32 cBufferAlloc,
5594                        BYTE buffer[],
5595                        ULONG32 * pcBufferSize);
5596     COM_METHOD GetVersionNumber( ULONG32 * nVersion);
5597     COM_METHOD GetILToNativeMapping(ULONG32 cMap,
5598                                     ULONG32 * pcMap,
5599                                     COR_DEBUG_IL_TO_NATIVE_MAP map[]) = 0;
5600     COM_METHOD GetEnCRemapSequencePoints(ULONG32 cMap,
5601                                          ULONG32 * pcMap,
5602                                          ULONG32 offsets[]);
5603
5604     //-----------------------------------------------------------
5605     // Accessors and convenience routines
5606     //-----------------------------------------------------------
5607
5608     // get the CordbFunction instance for this code object
5609     CordbFunction * GetFunction();
5610
5611     // get the actual code bytes for this function
5612     virtual HRESULT ReadCodeBytes() = 0;
5613
5614     // get the size in bytes of this function
5615     virtual ULONG32 GetSize() = 0;
5616
5617
5618     // get the metadata token for this code object
5619     mdMethodDef GetMetadataToken()
5620     {
5621         _ASSERTE(m_pFunction != NULL);
5622         return (m_pFunction->GetMetadataToken());
5623     }
5624  
5625     // get the module this code object belongs to
5626     CordbModule * GetModule()
5627     {
5628         _ASSERTE(m_pFunction != NULL);
5629         return (m_pFunction->GetModule());
5630     }
5631
5632     // get the function signature for this code blob or throw on failure
5633     void GetSig(SigParser *pMethodSigParser,
5634                 ULONG *pFunctionArgCount,
5635                 BOOL *pFunctionIsStatic)
5636     {
5637         _ASSERTE(m_pFunction != NULL);
5638         IfFailThrow(m_pFunction->GetSig(pMethodSigParser, pFunctionArgCount, pFunctionIsStatic));
5639     }
5640     
5641     // get the class to which this code blob belongs
5642     CordbClass * GetClass()
5643     {
5644         _ASSERTE(m_pFunction != NULL);
5645         return (m_pFunction->GetClass());
5646     }
5647
5648     // Quick helper to get the AppDomain that this code object lives in. 
5649     CordbAppDomain *GetAppDomain()
5650     {
5651         _ASSERTE(m_pFunction != NULL);
5652         return (m_pFunction->GetAppDomain());
5653     }
5654
5655     // Get the EnC version of this blob
5656     SIZE_T GetVersion() { return m_nVersion; };
5657
5658     // Return true if this is an IL code blob. Else return false.
5659     BOOL IsIL() { return m_fIsIL; }
5660
5661     // convert to CordbNativeCode as long as m_fIsIl is false.
5662     CordbNativeCode * AsNativeCode()
5663     {
5664         _ASSERTE(m_fIsIL == FALSE);
5665         return reinterpret_cast<CordbNativeCode *>(this);
5666     }
5667
5668     // convert to CordbILCode as long as m_fIsIl is true.
5669     CordbILCode * AsILCode()
5670     {
5671         _ASSERTE(m_fIsIL == TRUE);
5672         return reinterpret_cast<CordbILCode *>(this);
5673     }
5674
5675     //-----------------------------------------------------------
5676     // Data members
5677     //-----------------------------------------------------------
5678
5679 private:
5680     UINT m_fIsIL : 1;
5681
5682     // EnC version number.
5683     SIZE_T                 m_nVersion;
5684
5685 protected:
5686     // Our local copy of the code. It will be GetSize() bytes long.
5687     BYTE *                 m_rgbCode; // will be NULL if we can't fit it into memory
5688
5689     UINT                   m_continueCounterLastSync;
5690
5691     // Owning Function associated with this code.
5692     CordbFunction *        m_pFunction;
5693 }; //class CordbCode
5694
5695
5696
5697
5698
5699 /* ------------------------------------------------------------------------- *
5700 * CordbILCode class
5701 * This class represents an IL code blob for a particular EnC version. Thus it is 
5702 * 1:1 with a given instantiation of CordbFunction. Provided functionality includes
5703 * methods to get the starting address and size of an IL code blob and to read
5704 * the actual bytes of IL into a buffer. 
5705  * ------------------------------------------------------------------------- */
5706
5707 class CordbILCode : public CordbCode
5708 {
5709 public:
5710     // Initialize a new CordbILCode instance
5711     CordbILCode(CordbFunction *pFunction, TargetBuffer codeRegionInfo, SIZE_T nVersion, mdSignature localVarSigToken, UINT_PTR id = 0);
5712
5713 #ifdef _DEBUG
5714     const char * DbgGetName() { return "CordbILCode"; };
5715 #endif // _DEBUG
5716
5717     COM_METHOD GetAddress(CORDB_ADDRESS * pStart);
5718     COM_METHOD GetILToNativeMapping(ULONG32 cMap,
5719                                     ULONG32 * pcMap,
5720                                     COR_DEBUG_IL_TO_NATIVE_MAP map[]);
5721     // Quick helper for internal access to: GetAddress(CORDB_ADDRESS *pStart);
5722     CORDB_ADDRESS GetAddress() { return m_codeRegionInfo.pAddress; }
5723
5724     // get total size of the IL code
5725     ULONG32 GetSize() { return m_codeRegionInfo.cbSize; }
5726
5727 #ifdef EnC_SUPPORTED
5728     void MakeOld();
5729 #endif // EnC_SUPPORTED
5730
5731     HRESULT GetLocalVarSig(SigParser *pLocalsSigParser, ULONG *pLocalVarCount);
5732     HRESULT GetLocalVariableType(DWORD dwIndex, const Instantiation * pInst, CordbType ** ppResultType);
5733     mdSignature GetLocalVarSigToken();
5734
5735 private:
5736     // Read the actual bytes of IL code into the data member m_rgbCode.
5737     // Helper routine for GetCode
5738     HRESULT ReadCodeBytes();
5739
5740     //-----------------------------------------------------------
5741     // Data members
5742     //-----------------------------------------------------------
5743
5744 private:
5745 #ifdef EnC_SUPPORTED
5746     UINT m_fIsOld : 1;           // marks this instance as an old EnC version
5747     bool m_encBreakpointsApplied;
5748 #endif
5749
5750     // derived types can init this
5751 protected:
5752     TargetBuffer m_codeRegionInfo;  // stores the starting address and size of the 
5753                                     // IL code blob
5754
5755     // Metadata token for local's signature.    
5756     mdSignature m_localVarSigToken;
5757
5758 }; // class CordbILCode
5759
5760 /* ------------------------------------------------------------------------- *
5761 * CordbReJitILCode class
5762 * This class represents an IL code blob for a particular EnC version and
5763 * rejitID. Thus it is 1:N with a given instantiation of CordbFunction.
5764 * ------------------------------------------------------------------------- */
5765
5766 class CordbReJitILCode : public CordbILCode, public ICorDebugILCode, public ICorDebugILCode2
5767 {
5768 public:
5769     // Initialize a new CordbILCode instance
5770     CordbReJitILCode(CordbFunction *pFunction, SIZE_T encVersion, VMPTR_SharedReJitInfo vmSharedReJitInfo);
5771
5772     //-----------------------------------------------------------
5773     // IUnknown
5774     //-----------------------------------------------------------
5775     ULONG STDMETHODCALLTYPE AddRef();
5776     ULONG STDMETHODCALLTYPE Release();
5777     COM_METHOD QueryInterface(REFIID riid, void** ppInterface);
5778
5779
5780     //-----------------------------------------------------------
5781     // ICorDebugILCode
5782     //-----------------------------------------------------------
5783     COM_METHOD GetEHClauses(ULONG32 cClauses, ULONG32 * pcClauses, CorDebugEHClause clauses[]);
5784
5785
5786     //-----------------------------------------------------------
5787     // ICorDebugILCode2
5788     //-----------------------------------------------------------
5789     COM_METHOD GetLocalVarSigToken(mdSignature *pmdSig);
5790     COM_METHOD GetInstrumentedILMap(ULONG32 cMap, ULONG32 *pcMap, COR_IL_MAP map[]);
5791
5792 private:
5793     HRESULT Init(DacSharedReJitInfo* pSharedReJitInfo);
5794
5795 private:
5796     ULONG32 m_cClauses;
5797     NewArrayHolder<CorDebugEHClause> m_pClauses;
5798     ULONG32 m_cbLocalIL;
5799     NewArrayHolder<BYTE> m_pLocalIL;
5800     ULONG32 m_cILMap;
5801     NewArrayHolder<COR_IL_MAP> m_pILMap;
5802 };
5803
5804 /* ------------------------------------------------------------------------- *
5805  * CordbNativeCode class. These correspond to MethodDesc's on the left-side.
5806  * There may or may not be a DebuggerJitInfo associated with the MethodDesc.
5807  * At most one CordbNativeCode is created for each native code compilation of each method
5808  * that is seen by the right-side.  Note that if each method were JITted only once
5809  * then this information could go in CordbFunction, however generics allow
5810  * methods to be compiled more than once.
5811  *
5812  * The purpose of this class is to encapsulate details about a blob of jitted/ngen'ed
5813  * code, including an optional set of mappings from IL to offsets in the native Code.
5814  * ------------------------------------------------------------------------- */
5815
5816 class CordbNativeCode : public CordbCode, public ICorDebugCode2, public ICorDebugCode3
5817 {
5818 public:
5819     CordbNativeCode(CordbFunction * pFunction, 
5820                     const NativeCodeFunctionData * pJitData, 
5821                     BOOL fIsInstantiatedGeneric);
5822 #ifdef _DEBUG
5823     const char * DbgGetName() { return "CordbNativeCode"; };
5824 #endif // _DEBUG
5825
5826     ULONG STDMETHODCALLTYPE AddRef()
5827     {
5828         return (BaseAddRef());
5829     }
5830     ULONG STDMETHODCALLTYPE Release()
5831     {
5832         return (BaseRelease());
5833     }
5834     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
5835
5836     //-----------------------------------------------------------
5837     // ICorDebugCode
5838     //-----------------------------------------------------------
5839     COM_METHOD GetAddress(CORDB_ADDRESS * pStart);
5840     COM_METHOD GetILToNativeMapping(ULONG32 cMap,
5841                                     ULONG32 * pcMap,
5842                                     COR_DEBUG_IL_TO_NATIVE_MAP map[]);
5843     //-----------------------------------------------------------
5844     // ICorDebugCode2
5845     //-----------------------------------------------------------
5846     COM_METHOD GetCodeChunks(ULONG32 cbufSize, ULONG32 * pcnumChunks, CodeChunkInfo chunks[]);
5847
5848     COM_METHOD GetCompilerFlags(DWORD * pdwFlags);
5849
5850     //-----------------------------------------------------------
5851     // ICorDebugCode3
5852     //-----------------------------------------------------------
5853     COM_METHOD GetReturnValueLiveOffset(ULONG32 ILoffset, ULONG32 bufferSize, ULONG32 *pFetched, ULONG32 *pOffsets);
5854     
5855
5856     //-----------------------------------------------------------
5857     // Internal members
5858     //-----------------------------------------------------------
5859
5860     HRESULT ILVariableToNative(DWORD dwIndex,
5861                                SIZE_T ip,
5862                                const ICorDebugInfo::NativeVarInfo ** ppNativeInfo);
5863     void LoadNativeInfo();
5864
5865     //-----------------------------------------------------------
5866     // Accessors and convenience routines
5867     //-----------------------------------------------------------
5868
5869     // get the argument type for a generic 
5870     void GetArgumentType(DWORD                 dwIndex,
5871                          const Instantiation * pInst,
5872                          CordbType **          ppResultType)
5873     {
5874         CordbFunction * pFunction = GetFunction();
5875         _ASSERTE(pFunction != NULL);
5876         IfFailThrow(pFunction->GetArgumentType(dwIndex, pInst, ppResultType));
5877     }
5878
5879     // Quick helper for internall access to: GetAddress(CORDB_ADDRESS *pStart);
5880     CORDB_ADDRESS GetAddress() { return m_rgCodeRegions[kHot].pAddress; };
5881
5882     VMPTR_MethodDesc GetVMNativeCodeMethodDescToken() { return m_vmNativeCodeMethodDescToken; };
5883
5884     // Worker function for GetReturnValueLiveOffset.
5885     HRESULT GetReturnValueLiveOffsetImpl(Instantiation *currentInstantiation, ULONG32 ILoffset, ULONG32 bufferSize, ULONG32 *pFetched, ULONG32 *pOffsets);
5886
5887     // get total size of the code including both hot and cold regions
5888     ULONG32 GetSize();
5889
5890     // get the size of the cold region(s) only
5891     ULONG32 GetColdSize();
5892
5893     // Return true if the Code is split into hot + cold regions.
5894     bool HasColdRegion() { return m_rgCodeRegions[kCold].pAddress != NULL; }
5895
5896     // Get the number of fixed arguments for this function (the "this" 
5897     // but not varargs)
5898     unsigned int GetFixedArgCount()
5899     {
5900         return m_nativeVarData.GetFixedArgCount();
5901     }
5902
5903     // Get the number of all arguments for this function 
5904     // ("this" pointer, fixed args and varargs)
5905     ULONG32 GetAllArgsCount()
5906     {
5907         return m_nativeVarData.GetAllArgsCount();
5908     }
5909
5910     void SetAllArgsCount(ULONG32 count)
5911     {
5912         m_nativeVarData.SetAllArgsCount(count);
5913     }
5914
5915     // Determine whether this is an instantiation of a generic function
5916     BOOL IsInstantiatedGeneric()
5917     {
5918         return m_fIsInstantiatedGeneric != 0;
5919     }
5920
5921     // Determine whether we have initialized the native variable and 
5922     // sequence point offsets
5923     BOOL IsNativeCodeValid ()
5924     {
5925         return ((m_nativeVarData.IsInitialized() != 0) && 
5926                (m_sequencePoints.IsInitialized() != 0));
5927     }
5928
5929     SequencePoints * GetSequencePoints()
5930     {
5931         return &m_sequencePoints;
5932     }
5933
5934
5935     // Given an ILOffset in the current function, return the class token and function token of the IL call target at that
5936     // location.  Also fill "methodSig" with the method's signature and "genericSig" with the method's generic signature.
5937     HRESULT GetCallSignature(ULONG32 ILOffset, mdToken *pClass, mdToken *pMDFunction, SigParser &methodSig, SigParser &genericSig);
5938
5939     // Moves a method signature from the start of the signature to the location of the return value (passing out the
5940     // number of generic parameters in the method).
5941     static HRESULT SkipToReturn(SigParser &parser, ULONG *genArgCount = 0);
5942
5943 private:
5944     // Read the actual bytes of native code into the data member m_rgbCode.
5945     // Helper routine for GetCode
5946     HRESULT ReadCodeBytes();
5947
5948     // Returns a failure HRESULT if we cannot handle the return value of the given
5949     // methodref, methoddef, or methodspec token, otherwise S_OK.  Does NOT return S_FALSE;
5950     HRESULT EnsureReturnValueAllowed(Instantiation *currentInstantiation, mdToken targetClass, SigParser &parser, SigParser &methodGenerics);
5951     HRESULT EnsureReturnValueAllowedWorker(Instantiation *currentInstantiation, mdToken targetClass, SigParser &parser, SigParser &methodGenerics, ULONG genCount);
5952     
5953     // Grabs the appropriate signature parser for a methodref, methoddef, methodspec.
5954     HRESULT GetSigParserFromFunction(mdToken mdFunction, mdToken *pClass, SigParser &methodSig, SigParser &genericSig);
5955
5956     int GetCallInstructionLength(BYTE *buffer, ULONG32 len);
5957
5958     //-----------------------------------------------------------
5959     // Data members
5960     //-----------------------------------------------------------
5961 private:
5962     // offset of the beginning of the last sequence point in the sequence point map
5963     SIZE_T                   m_lastIL;
5964
5965     // start address(es) and size(s) of hot and cold regions
5966     TargetBuffer             m_rgCodeRegions[MAX_REGIONS];
5967
5968     // LS data structure--method desc for this instantiation.
5969     VMPTR_MethodDesc         m_vmNativeCodeMethodDescToken;
5970
5971     bool                     m_fCodeAvailable;          // true iff the code has been jitted but not pitched
5972
5973     bool                     m_fIsInstantiatedGeneric;  // true iff this is an instantiated generic
5974
5975     // information in the following two classes tracks native offsets and is initialized on demand. 
5976
5977     // location and ID information for local variables. See code:NativeVarData for details.
5978     NativeVarData            m_nativeVarData;
5979
5980     // mapping between IL and native code sequence points. 
5981     SequencePoints           m_sequencePoints;
5982
5983 }; //class CordbNativeCode
5984
5985 //---------------------------------------------------------------------------------------
5986 //
5987 // GetActiveInternalFramesData is used to enumerate internal frames on a specific thread.
5988 // It is used in conjunction with code:CordbThread::GetActiveInternalFramesCallback.
5989 // We store each internal frame in ppInternalFrames as we enumerate them.
5990 //
5991
5992 struct GetActiveInternalFramesData
5993 {
5994 public:
5995     // the thread we are walking
5996     CordbThread * pThis;
5997
5998     // an array to store the internal frames
5999     RSPtrArray<CordbInternalFrame> pInternalFrames;
6000
6001     // next element in the array to be filled
6002     ULONG32 uIndex;
6003 };
6004
6005
6006 /* ------------------------------------------------------------------------- *
6007  * Thread classes
6008  * ------------------------------------------------------------------------- */
6009
6010 class CordbThread : public CordbBase, public ICorDebugThread,
6011                                       public ICorDebugThread2,
6012                                       public ICorDebugThread3,
6013                                       public ICorDebugThread4
6014 {
6015 public:
6016     CordbThread(CordbProcess * pProcess, VMPTR_Thread);
6017
6018     virtual ~CordbThread();
6019     virtual void Neuter();
6020
6021     using CordbBase::GetProcess;
6022     
6023 #ifdef _DEBUG
6024     virtual const char * DbgGetName() { return "CordbThread"; }
6025 #endif
6026
6027     //-----------------------------------------------------------
6028     // IUnknown
6029     //-----------------------------------------------------------
6030
6031     ULONG STDMETHODCALLTYPE AddRef()
6032     {
6033         // there's an external add ref from within RS in CordbEnumFilter
6034         return (BaseAddRef());
6035     }
6036     ULONG STDMETHODCALLTYPE Release()
6037     {
6038         return (BaseRelease());
6039     }
6040     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6041
6042     //-----------------------------------------------------------
6043     // ICorDebugThread
6044     //-----------------------------------------------------------
6045
6046     COM_METHOD GetProcess(ICorDebugProcess **ppProcess);
6047     COM_METHOD GetID(DWORD *pdwThreadId);
6048     COM_METHOD GetHandle(HANDLE * phThreadHandle);
6049     COM_METHOD GetAppDomain(ICorDebugAppDomain **ppAppDomain);
6050     COM_METHOD SetDebugState(CorDebugThreadState state);
6051     COM_METHOD GetDebugState(CorDebugThreadState *pState);
6052     COM_METHOD GetUserState(CorDebugUserState *pState);
6053     COM_METHOD GetCurrentException(ICorDebugValue ** ppExceptionObject);
6054     COM_METHOD ClearCurrentException();
6055     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper);
6056     COM_METHOD EnumerateChains(ICorDebugChainEnum **ppChains);
6057     COM_METHOD GetActiveChain(ICorDebugChain **ppChain);
6058     COM_METHOD GetActiveFrame(ICorDebugFrame **ppFrame);
6059     COM_METHOD GetRegisterSet(ICorDebugRegisterSet **ppRegisters);
6060     COM_METHOD CreateEval(ICorDebugEval **ppEval);
6061     COM_METHOD GetObject(ICorDebugValue ** ppObject);
6062
6063     // ICorDebugThread2
6064     COM_METHOD GetConnectionID(CONNID * pConnectionID);
6065     COM_METHOD GetTaskID(TASKID * pTaskID);
6066     COM_METHOD GetVolatileOSThreadID(DWORD * pdwTID);
6067     COM_METHOD GetActiveFunctions(ULONG32 cFunctions, ULONG32 * pcFunctions, COR_ACTIVE_FUNCTION pFunctions[]);
6068     // Intercept the current exception at the specified frame.  pFrame must be a valid ICDFrame, possibly from
6069     // a previous stackwalk.
6070     COM_METHOD InterceptCurrentException(ICorDebugFrame * pFrame);
6071
6072
6073
6074     // ICorDebugThread3
6075     COM_METHOD CreateStackWalk(ICorDebugStackWalk **ppStackWalk);
6076
6077     COM_METHOD GetActiveInternalFrames(ULONG32 cInternalFrames,
6078                                        ULONG32 * pcInternalFrames,
6079                                        ICorDebugInternalFrame2 * ppInternalFrames[]);
6080
6081     // ICorDebugThread4
6082     COM_METHOD HasUnhandledException();
6083
6084     COM_METHOD GetBlockingObjects(ICorDebugBlockingObjectEnum **ppBlockingObjectEnum);
6085
6086     // Gets the current CustomNotification object from the thread or NULL if no such object exists 
6087     COM_METHOD GetCurrentCustomDebuggerNotification(ICorDebugValue ** ppNotificationObject);
6088     //-----------------------------------------------------------
6089     // Internal members
6090     //-----------------------------------------------------------
6091
6092     // callback used to enumerate the internal frames on a thread 
6093     static void GetActiveInternalFramesCallback(const DebuggerIPCE_STRData * pFrameData,
6094                                                 void *                 pUserData);
6095
6096     CorDebugUserState GetUserState();
6097
6098     // Given a FramePointer, find the matching CordbFrame.
6099     HRESULT FindFrame(ICorDebugFrame ** ppFrame, FramePointer fp);
6100
6101     // Get the task ID for this thread.
6102     TASKID GetTaskID();
6103
6104     void RefreshStack();
6105     void CleanupStack();
6106     void MarkStackFramesDirty();
6107
6108 #if !defined(DBG_TARGET_ARM) // @ARMTODO
6109
6110 #if defined(DBG_TARGET_X86)
6111     // Converts the values in the floating point register area of the context to real number values.
6112     void Get32bitFPRegisters(CONTEXT * pContext);
6113
6114 #elif defined(DBG_TARGET_AMD64)
6115     // Converts the values in the floating point register area of the context to real number values.
6116     void Get64bitFPRegisters(FPRegister64 * rgContextFPRegisters, int start, int nRegisters);
6117 #endif // DBG_TARGET_X86
6118
6119    // Initializes the float state members of this instance of CordbThread. This function gets the context and
6120    // converts the floating point values from their context representation to real number values.    
6121    void LoadFloatState();
6122
6123 #endif //!DBG_TARGET_ARM @ARMTODO
6124
6125     HRESULT SetIP(  bool fCanSetIPOnly,
6126                     CordbNativeCode * pNativeCode,
6127                     SIZE_T offset,
6128                     bool fIsIL );
6129
6130     // Tells the LS to remap to the latest version of the function
6131     HRESULT SetRemapIP(SIZE_T offset);
6132
6133     // Ask the left-side for the current (up-to-date) AppDomain of this thread's IP.
6134     // This should be preferred over using the cached value from GetAppDomain.
6135     HRESULT GetCurrentAppDomain(CordbAppDomain ** ppAppDomain);
6136
6137     //-----------------------------------------------------------
6138     // Convenience routines
6139     //-----------------------------------------------------------
6140
6141     // The last domain from which a debug event for this thread was sent.
6142     // This usually (but not always) the domain the thread is currently executing in.
6143     // Since this is a cache, it may sometimes be out-of-date.  I believe all current
6144     // usage of this is OK (we pass AppDomains around a lot without really using them),
6145     // but no new code should rely on this value.
6146     // TODO: eliminate this and the m_pAppDomain field entirely
6147     CordbAppDomain *GetAppDomain()
6148     {
6149         return (m_pAppDomain);
6150     }
6151
6152     DWORD GetVolatileOSThreadID();
6153
6154     //////////////////////////////////////////////////////////////////////////
6155     //
6156     // Get Context
6157     //
6158     //      <TODO>TODO: Since Thread will share the memory with RegisterSets, how
6159     //      do we know that the RegisterSets have relinquished all pointers
6160     //      to the m_pContext structure?</TODO>
6161     //
6162     // Returns: NULL if the thread's CONTEXT structure couldn't be obtained
6163     //   A pointer to the CONTEXT otherwise.
6164     //
6165     //
6166     //////////////////////////////////////////////////////////////////////////
6167     HRESULT GetManagedContext( DT_CONTEXT ** ppContext );
6168     HRESULT SetManagedContext( DT_CONTEXT * pContext );
6169
6170     // API to retrieve the thread handle from the LS.
6171     void InternalGetHandle(HANDLE * phThread);
6172     void RefreshHandle(HANDLE * phThread);
6173
6174     // NeuterList that's executed when this Thread's stack is refreshed.
6175     // Chain + Frame + some Value enums can be held on this.
6176     NeuterList * GetRefreshStackNeuterList()
6177     {
6178         return &m_RefreshStackNeuterList;
6179     }
6180
6181     DWORD GetUniqueId();
6182
6183
6184     // Hijack a thread at a 2nd-chance exception so that it can execute the CLR's UEF
6185     void HijackForUnhandledException();
6186
6187     // check whether the specified frame lives on the stack of the current thread
6188     bool OwnsFrame(CordbFrame *pFrame);
6189
6190     // Specify that there's an outstanding exception on this thread.
6191     void SetExInfo(VMPTR_OBJECTHANDLE vmExcepObjHandle);
6192
6193     VMPTR_OBJECTHANDLE GetThreadExceptionRawObjectHandle() { return m_vmExcepObjHandle; }
6194     bool HasException() { return m_fException; }
6195
6196     void SetUnhandledNativeException(const EXCEPTION_RECORD * pExceptionRecord);
6197     bool HasUnhandledNativeException();
6198
6199 #ifdef _DEBUG
6200     // Helper to assert that this thread no longer appears in dac-dbi enumerations
6201     void DbgAssertThreadDeleted();
6202
6203     // Callback for DbgAssertThreadDeleted
6204     static void DbgAssertThreadDeletedCallback(VMPTR_Thread vmThread, void * pUserData);
6205 #endif // _DEBUG
6206
6207     // Determine if the thread's current exception is managed or unmanaged.
6208     BOOL IsThreadExceptionManaged();
6209
6210     // This is a private hook for the shim to create a CordbRegisterSet for a ShimChain.
6211    void CreateCordbRegisterSet(DT_CONTEXT *            pContext, 
6212                                BOOL                    fActive,
6213                                CorDebugChainReason     reason,
6214                                ICorDebugRegisterSet ** ppRegSet);
6215
6216     // This is a private hook for the shim to convert an ICDFrame into an ICDInternalFrame for a dynamic
6217     // method.  Refer to the function header for more information.
6218    BOOL ConvertFrameForILMethodWithoutMetadata(ICorDebugFrame *           pFrame,
6219                                                ICorDebugInternalFrame2 ** ppInternalFrame2);
6220
6221     // Gets/sets m_fCreationEventQueued
6222     bool CreateEventWasQueued();
6223     void SetCreateEventQueued();
6224
6225     //-----------------------------------------------------------
6226     // Data members
6227     //-----------------------------------------------------------
6228
6229 public:
6230     // RS Cache for LS context.
6231     // NULL if we haven't allocated memory for a Right side context
6232     DT_CONTEXT *          m_pContext;
6233
6234     // Set to the CONTEXT pointer in the LS if this LS thread is
6235     // stopped in managed code. This may be either stopped for execution control
6236     // (breakpoint / single-step exception) or hijacked w/ a redirected frame because
6237     // another thread synced the LS.
6238     // This context is used by the RS to set enregistered vars.
6239     VMPTR_CONTEXT         m_vmLeftSideContext;
6240
6241     // indicates whether m_pContext is up-to-date
6242     bool                  m_fContextFresh;
6243
6244     // last domain we've seen this thread.
6245     // If the appdomain exits, it will clear out this value.
6246     CordbAppDomain       *m_pAppDomain;
6247
6248     // Handle to VM's Thread* object. This is the primary key for a CordbThread object
6249     // @dbgtodo  ICDThread - merge with m_id;
6250     VMPTR_Thread          m_vmThreadToken;
6251
6252     // Unique ID for this thread. See code:CordbThread::GetID for semantics of this field.
6253     DWORD                 m_dwUniqueID;
6254
6255     CorDebugThreadState   m_debugState; // Note that this is for resume
6256                                         // purposes, NOT the current state of
6257                                         // the thread.
6258
6259     // The frames are all protected under the Stop-Go lock.
6260     // This field indicates whether the stack is valid (i.e. no update is necessary).
6261     bool                  m_fFramesFresh;
6262
6263     // This is a cache of V3 ICDFrames.  The cache is only used by two functions: 
6264     //     - code:CordbThread::GetActiveFunctions 
6265     //     - code:CordbThread::InterceptCurrentException.
6266     //     
6267     //  We don't clear the cache in CleanupStack() because we don't refresh the cache every time we stop.  
6268     //  Instead, we mark m_fFramesFresh in CleanupStack() and clear the cache only when it is used next time.
6269     CDynArray<CordbFrame *> m_stackFrames;
6270
6271 #if !defined(DBG_TARGET_ARM) // @ARMTODO
6272     bool                  m_fFloatStateValid;
6273     unsigned int          m_floatStackTop;
6274     double                m_floatValues[DebuggerIPCE_FloatCount];
6275 #endif // !DBG_TARGET_ARM @ARMTODO
6276
6277 private:
6278     // True for the window after an Exception callback, but before it's been continued.
6279     // We dispatch two exception events in a row (ICDManagedCallback::Exception and ICDManagedCallback2::Exception),
6280     // and a debugger may normally just skip the first one knowing it can stop on the 2nd once.
6281     // Both events will set this bit high. Be careful not to reset this bit inbetween them.
6282     bool                  m_fException;
6283
6284     // True if a creation event has been queued for this thread
6285     // The event may or may not have been dispatched yet
6286     // Bugfix DevDiv2\DevDiv 77523 - this is only being set from ShimProcess::QueueFakeThreadAttachEventsNativeOrder
6287     bool                  m_fCreationEventQueued;
6288
6289     // Object handle for Exception object in debuggee.
6290     VMPTR_OBJECTHANDLE    m_vmExcepObjHandle;
6291    
6292 public:
6293
6294     //Returns true if current user state of a thread is USER_WAIT_SLEEP_JOIN
6295     bool IsThreadWaitingOrSleeping();
6296
6297     // Returns true if the thread is dead. See function header for definition.
6298     bool IsThreadDead();
6299
6300     // Return CORDBG_E_BAD_THREAD_STATE if the thread is dead.
6301     HRESULT EnsureThreadIsAlive();
6302
6303     // On a RemapBreakpoint, the debugger will eventually call RemapFunction and
6304     // we need to communicate the IP back to LS. So we stash the address of where
6305     // to store the IP here and stuff it in on RemapFunction.
6306     // If we're not at an outstanding RemapOpportunity, this will be NULL
6307     REMOTE_PTR            m_EnCRemapFunctionIP;
6308
6309 private:
6310     void ClearStackFrameCache();
6311
6312     // True iff this thread has an unhandled exception on it. 
6313     // Set high when Filter() gets noitifed of an unhandled exception.
6314     // Set Low if the thread is hijacked.
6315     bool                  m_fHasUnhandledException;
6316
6317     // Exception record for last unhandled exception on this thread.
6318     // Lazily initialized. 
6319     EXCEPTION_RECORD *  m_pExceptionRecord; 
6320
6321     static const CorDebugUserState kInvalidUserState = CorDebugUserState(-1);
6322     CorDebugUserState     m_userState;  // This is the current state of the
6323                                         // thread, at the time that the
6324                                         // left side synchronized
6325
6326     // NeuterList that's executed when this Thread's stack is refreshed.
6327     // This list is for everything related to stackwalking, i.e. everything which is invalidated 
6328     // if the stack changes in any way.  This list is cleared when any of the following is called:
6329     //     1) Continue()
6330     //     2) SetIP()
6331     //     3) RemapFunction()
6332     //     4) ICDProcess::SetThreadContext()
6333     NeuterList            m_RefreshStackNeuterList;
6334
6335     // The following two data members are used for caching thread handles.
6336     // @dbgtodo  - Remove in V3 (can't have local handles with data-target abstraction); 
6337     // offload to the shim to support V2 scenarios.
6338     HANDLE                m_hCachedThread;
6339     HANDLE                m_hCachedOutOfProcThread;
6340 };
6341
6342 /* ------------------------------------------------------------------------- *
6343  * StackWalk class
6344  * ------------------------------------------------------------------------- */
6345
6346 class CordbStackWalk : public CordbBase, public ICorDebugStackWalk
6347 {
6348 public:
6349     CordbStackWalk(CordbThread * pCordbThread);
6350     virtual ~CordbStackWalk();
6351     virtual void Neuter();
6352
6353     // helper function for Neuter
6354     virtual void DeleteAll();
6355
6356     using CordbBase::GetProcess;
6357     
6358 #ifdef _DEBUG
6359     virtual const char * DbgGetName() { return "CordbStackWalk"; }
6360 #endif
6361
6362     //-----------------------------------------------------------
6363     // IUnknown
6364     //-----------------------------------------------------------
6365
6366     ULONG STDMETHODCALLTYPE AddRef()
6367     {
6368         return (BaseAddRef());
6369     }
6370     ULONG STDMETHODCALLTYPE Release()
6371     {
6372         return (BaseRelease());
6373     }
6374     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6375
6376     //-----------------------------------------------------------
6377     // ICorDebugStackWalk
6378     //-----------------------------------------------------------
6379
6380     COM_METHOD GetContext(ULONG32   contextFlags,
6381                           ULONG32   contextBufSize,
6382                           ULONG32 * pContextSize,
6383                           BYTE      pbContextBuf[]);
6384     COM_METHOD SetContext(CorDebugSetContextFlag flag, ULONG32 contextSize, BYTE context[]);
6385     COM_METHOD Next();
6386     COM_METHOD GetFrame(ICorDebugFrame **ppFrame);
6387
6388     //-----------------------------------------------------------
6389     // Internal members
6390     //-----------------------------------------------------------
6391
6392     void SetContextWorker(CorDebugSetContextFlag flag, ULONG32 contextSize, BYTE context[]);
6393     HRESULT GetFrameWorker(ICorDebugFrame **ppFrame);
6394
6395     //-----------------------------------------------------------
6396     // Data members
6397     //-----------------------------------------------------------
6398
6399 public:
6400     void Init();
6401
6402 private:
6403     // handle legacy V2 hijacking for unhandled hardware exceptions
6404     void CheckForLegacyHijackCase();
6405
6406     // refresh the data for this instance of CordbStackWalk if we have had an IPC event followed by a
6407     // continue since we got the information.
6408     void RefreshIfNeeded();
6409
6410     // unwind the frame and update m_context with the new context
6411     BOOL UnwindStackFrame();
6412
6413     // the thread on which this CordbStackWalk is created
6414     CordbThread * m_pCordbThread;
6415
6416     // This is the same iterator used by the runtime itself.
6417     IDacDbiInterface::StackWalkHandle m_pSFIHandle;
6418
6419     // buffers used for stackwalking
6420     DT_CONTEXT m_context;
6421
6422     //  Used to figure out if we have to refresh any reference objects
6423     //  on the left side.  We set it to CordbProcess::m_flushCounter on 
6424     //  creation and will check it against that value when we call GetFrame or Next.
6425     //  If it doesn't match, an IPC event has occurred and the values will need to be 
6426     //  refreshed via the DAC.
6427     UINT m_lastSyncFlushCounter;
6428
6429     // cached flag used for refreshing a CordbStackWalk
6430     CorDebugSetContextFlag m_cachedSetContextFlag;
6431
6432     // We unwind one frame ahead of time to get the FramePointer on x86.
6433     // These fields are used for the bookkeeping.
6434     RSSmartPtr<CordbFrame> m_pCachedFrame;
6435     HRESULT m_cachedHR;
6436     bool m_fIsOneFrameAhead;
6437 };
6438
6439
6440 class CordbContext : public CordbBase, public ICorDebugContext
6441 {
6442 public:
6443
6444     CordbContext() : CordbBase(NULL, 0, enumCordbContext) {}
6445
6446
6447
6448 #ifdef _DEBUG
6449     virtual const char * DbgGetName() { return "CordbContext"; }
6450 #endif
6451
6452
6453     //-----------------------------------------------------------
6454     // IUnknown
6455     //-----------------------------------------------------------
6456
6457     ULONG STDMETHODCALLTYPE AddRef()
6458     {
6459         return (BaseAddRef());
6460     }
6461     ULONG STDMETHODCALLTYPE Release()
6462     {
6463         return (BaseRelease());
6464     }
6465     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6466
6467     //-----------------------------------------------------------
6468     // ICorDebugContext
6469     //-----------------------------------------------------------
6470 private:
6471
6472 } ;
6473
6474
6475 /* ------------------------------------------------------------------------- *
6476  * Frame class
6477  * ------------------------------------------------------------------------- */
6478
6479 class CordbFrame : public CordbBase, public ICorDebugFrame
6480 {
6481 protected:
6482     // Ctor to provide dummy frame that just wraps a frame-pointer
6483     CordbFrame(CordbProcess * pProcess, FramePointer fp);
6484
6485 public:
6486     CordbFrame(CordbThread *    pThread,
6487                FramePointer     fp,
6488                SIZE_T           ip, 
6489                CordbAppDomain * pCurrentAppDomain);
6490
6491     virtual ~CordbFrame();
6492     virtual void Neuter();
6493
6494 #ifdef _DEBUG
6495     virtual const char * DbgGetName() { return "CordbFrame"; }
6496 #endif
6497
6498     //-----------------------------------------------------------
6499     // IUnknown
6500     //-----------------------------------------------------------
6501
6502     ULONG STDMETHODCALLTYPE AddRef()
6503     {
6504         return (BaseAddRef());
6505     }
6506     ULONG STDMETHODCALLTYPE Release()
6507     {
6508         return (BaseRelease());
6509     }
6510     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6511
6512     //-----------------------------------------------------------
6513     // ICorDebugFrame
6514     //-----------------------------------------------------------
6515
6516     COM_METHOD GetChain(ICorDebugChain **ppChain);
6517
6518     // Derived versions of Frame will implement GetCode.
6519     COM_METHOD GetCode(ICorDebugCode **ppCode) = 0;
6520
6521     COM_METHOD GetFunction(ICorDebugFunction **ppFunction);
6522     COM_METHOD GetFunctionToken(mdMethodDef *pToken);
6523
6524     COM_METHOD GetStackRange(CORDB_ADDRESS *pStart, CORDB_ADDRESS *pEnd);
6525     COM_METHOD GetCaller(ICorDebugFrame **ppFrame);
6526     COM_METHOD GetCallee(ICorDebugFrame **ppFrame);
6527     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper);
6528
6529     //-----------------------------------------------------------
6530     // Convenience routines
6531     //-----------------------------------------------------------
6532
6533     CordbAppDomain *GetCurrentAppDomain()
6534     {
6535         return m_currentAppDomain;
6536     }
6537
6538     // Internal helper to get a CordbFunction for this frame.
6539     virtual CordbFunction *GetFunction() = 0;
6540
6541     FramePointer GetFramePointer()
6542     {
6543         return m_fp;
6544     }
6545
6546     //-----------------------------------------------------------
6547     // Data members
6548     //-----------------------------------------------------------
6549
6550     // Accessors to return NULL or typesafe cast to derived frame
6551     virtual CordbInternalFrame * GetAsInternalFrame()   { return NULL; }
6552     virtual CordbNativeFrame * GetAsNativeFrame()       { return NULL; }
6553
6554     // determine if the frame pointer is in the stack range owned by the frame
6555     bool IsContainedInFrame(FramePointer fp);
6556
6557     // This is basically a complicated cast function.  We are casting from an ICorDebugFrame to a CordbFrame.
6558     static CordbFrame* GetCordbFrameFromInterface(ICorDebugFrame *pFrame);
6559
6560     virtual const DT_CONTEXT * GetContext() const { return NULL; }
6561
6562 public:
6563     // this represents the IL offset for a CordbJITILFrame, the native offset for a CordbNativeFrame, 
6564     // and 0 for a CordbInternalFrame
6565     SIZE_T                  m_ip;
6566
6567     CordbThread *           m_pThread;
6568
6569     CordbAppDomain         *m_currentAppDomain;
6570     FramePointer            m_fp;
6571
6572 protected:
6573     // indicates whether this frame is the leaf frame; lazily initialized
6574     mutable Optional<bool>  m_optfIsLeafFrame;
6575
6576 private:
6577 #ifdef _DEBUG
6578     // For tracking down neutering bugs;
6579     UINT                   m_DbgContinueCounter;
6580 #endif
6581 };
6582
6583 // Dummy frame that just wraps a frame pointer.
6584 // This is used to pass a FramePointer back in the Exception2 callback.
6585 // Currently, the callback passes back an ICorDebugFrame as a way of exposing a cross-platform
6586 // frame pointer. However passing back an ICDFrame means we need to do a stackwalk, and
6587 // that may not be possible in V3:
6588 // - the stackwalk is very chatty, and may be too much work just to give an exception notification.
6589 // - in 64-bit, we may not even be able to do the stackwalk ourselves.
6590 //
6591 // The shim can take the framePointer and do the stackwalk and resolve it to a real frame,
6592 // so V2 emulation scenarios will continue to work.
6593 // @dbgtodo  exception -  resolve this when we iron out exceptions in V3.
6594 class CordbPlaceholderFrame : public CordbFrame
6595 {
6596 public:
6597     // Ctor to provide dummy frame that just wraps a frame-pointer
6598     CordbPlaceholderFrame(CordbProcess * pProcess, FramePointer fp)
6599         : CordbFrame(pProcess, fp)
6600     {
6601     }
6602
6603 #ifdef _DEBUG
6604     virtual const char * DbgGetName() { return "CordbFrame"; }
6605 #endif
6606
6607     // Provide dummy implementation for some methods. These should never be called.
6608     COM_METHOD GetCode(ICorDebugCode **ppCode) 
6609     { 
6610         _ASSERTE(!"Don't call this");
6611         return E_NOTIMPL; 
6612     }
6613     virtual CordbFunction *GetFunction() 
6614     { 
6615         _ASSERTE(!"Don't call this");
6616         return NULL; 
6617     } 
6618 };
6619
6620 class CordbInternalFrame : public CordbFrame, public ICorDebugInternalFrame, public ICorDebugInternalFrame2
6621 {
6622 public:
6623     CordbInternalFrame(CordbThread *          pThread,
6624                        FramePointer           fp,
6625                        CordbAppDomain *       pCurrentAppDomain,
6626                        const DebuggerIPCE_STRData * pData);
6627
6628     CordbInternalFrame(CordbThread *             pThread,
6629                        FramePointer              fp,
6630                        CordbAppDomain *       pCurrentAppDomain,
6631                        CorDebugInternalFrameType frameType,
6632                        mdMethodDef               funcMetadataToken,
6633                        CordbFunction *           pFunction,
6634                        VMPTR_MethodDesc          vmMethodDesc);
6635
6636     virtual void Neuter();
6637
6638 #ifdef _DEBUG
6639     virtual const char * DbgGetName() { return "CordbInternalFrame"; }
6640 #endif
6641
6642     //-----------------------------------------------------------
6643     // IUnknown
6644     //-----------------------------------------------------------
6645
6646     ULONG STDMETHODCALLTYPE AddRef()
6647     {
6648         return (BaseAddRef());
6649     }
6650     ULONG STDMETHODCALLTYPE Release()
6651     {
6652         return (BaseRelease());
6653     }
6654     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6655
6656     //-----------------------------------------------------------
6657     // ICorDebugFrame
6658     //-----------------------------------------------------------
6659
6660     COM_METHOD GetChain(ICorDebugChain **ppChain)
6661     {
6662         return (CordbFrame::GetChain(ppChain));
6663     }
6664
6665     // We don't expose a code-object for stubs.
6666     COM_METHOD GetCode(ICorDebugCode **ppCode)
6667     {
6668         return CORDBG_E_CODE_NOT_AVAILABLE;
6669     }
6670
6671     COM_METHOD GetFunction(ICorDebugFunction **ppFunction)
6672     {
6673         return (CordbFrame::GetFunction(ppFunction));
6674     }
6675     COM_METHOD GetFunctionToken(mdMethodDef *pToken)
6676     {
6677         return (CordbFrame::GetFunctionToken(pToken));
6678     }
6679
6680     COM_METHOD GetCaller(ICorDebugFrame **ppFrame)
6681     {
6682         return (CordbFrame::GetCaller(ppFrame));
6683     }
6684     COM_METHOD GetCallee(ICorDebugFrame **ppFrame)
6685     {
6686         return (CordbFrame::GetCallee(ppFrame));
6687     }
6688     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper)
6689     {
6690         return E_NOTIMPL;
6691     }
6692
6693     COM_METHOD GetStackRange(CORDB_ADDRESS *pStart, CORDB_ADDRESS *pEnd);
6694
6695     //-----------------------------------------------------------
6696     // ICorDebugInternalFrame
6697     //-----------------------------------------------------------
6698
6699     // Get the type of internal frame. This will never be STUBFRAME_NONE.
6700     COM_METHOD GetFrameType(CorDebugInternalFrameType * pType)
6701     {
6702         VALIDATE_POINTER_TO_OBJECT(pType, CorDebugInternalFrameType)
6703         *pType = m_eFrameType;
6704         return S_OK;
6705     }
6706
6707     //-----------------------------------------------------------
6708     // ICorDebugInternalFrame2
6709     //-----------------------------------------------------------
6710
6711     COM_METHOD GetAddress(CORDB_ADDRESS * pAddress);
6712     COM_METHOD IsCloserToLeaf(ICorDebugFrame * pFrameToCompare, 
6713                               BOOL *           pIsCloser);
6714
6715     BOOL IsCloserToLeafWorker(ICorDebugFrame * pFrameToCompare);
6716
6717     //-----------------------------------------------------------
6718     // Non COM methods
6719     //-----------------------------------------------------------
6720
6721     virtual CordbFunction *GetFunction();
6722
6723
6724     // Accessors to return NULL or typesafe cast to derived frame
6725     virtual CordbInternalFrame * GetAsInternalFrame()   { return this; }
6726
6727     // accessor for the shim private hook code:CordbThread::ConvertFrameForILMethodWithoutMetadata
6728     BOOL ConvertInternalFrameForILMethodWithoutMetadata(ICorDebugInternalFrame2 ** ppInternalFrame2);
6729
6730 protected:
6731     // the frame type
6732     CorDebugInternalFrameType m_eFrameType;
6733     
6734     // the method token of the method (if any) associated with the internal frame
6735     mdMethodDef m_funcMetadataToken;
6736
6737     // the method (if any) associated with the internal frame
6738     RSSmartPtr<CordbFunction> m_function;
6739
6740     VMPTR_MethodDesc          m_vmMethodDesc;
6741 };
6742
6743 //---------------------------------------------------------------------------------------
6744 //
6745 // This class implements ICorDebugRuntimeUnwindableFrame.  It is used to mark a native stack frame 
6746 // which requires special unwinding and which doesn't correspond to any IL code.  It is really
6747 // just a marker to tell the debugger to use the managed unwinder.  The debugger is still responsible
6748 // to do all the inspection and symbol lookup.  An example is the hijack stub.
6749 //
6750
6751 class CordbRuntimeUnwindableFrame : public CordbFrame, public ICorDebugRuntimeUnwindableFrame
6752 {
6753 public:
6754     CordbRuntimeUnwindableFrame(CordbThread *    pThread,
6755                                 FramePointer     fp,
6756                                 CordbAppDomain * pCurrentAppDomain,
6757                                 DT_CONTEXT *     pContext);
6758
6759     virtual void Neuter();
6760
6761 #ifdef _DEBUG
6762     virtual const char * DbgGetName() { return "CordbRuntimeUnwindableFrame"; }
6763 #endif
6764
6765     //-----------------------------------------------------------
6766     // IUnknown
6767     //-----------------------------------------------------------
6768
6769     ULONG STDMETHODCALLTYPE AddRef()
6770     {
6771         return (BaseAddRef());
6772     }
6773
6774     ULONG STDMETHODCALLTYPE Release()
6775     {
6776         return (BaseRelease());
6777     }
6778
6779     COM_METHOD QueryInterface(REFIID riid, void ** ppInterface);
6780
6781     //-----------------------------------------------------------
6782     // ICorDebugFrame
6783     //-----------------------------------------------------------
6784
6785     // 
6786     // Just return E_NOTIMPL for everything.  
6787     // See the class comment.
6788     //
6789
6790     COM_METHOD GetChain(ICorDebugChain ** ppChain)
6791     {
6792         return E_NOTIMPL;
6793     }
6794
6795     COM_METHOD GetCode(ICorDebugCode ** ppCode)
6796     {
6797         return E_NOTIMPL;
6798     }
6799
6800     COM_METHOD GetFunction(ICorDebugFunction ** ppFunction)
6801     {
6802         return E_NOTIMPL;
6803     }
6804
6805     COM_METHOD GetFunctionToken(mdMethodDef * pToken)
6806     {
6807         return E_NOTIMPL;
6808     }
6809
6810     COM_METHOD GetCaller(ICorDebugFrame ** ppFrame)
6811     {
6812         return E_NOTIMPL;
6813     }
6814
6815     COM_METHOD GetCallee(ICorDebugFrame ** ppFrame)
6816     {
6817         return E_NOTIMPL;
6818     }
6819
6820     COM_METHOD CreateStepper(ICorDebugStepper ** ppStepper)
6821     {
6822         return E_NOTIMPL;
6823     }
6824
6825     COM_METHOD GetStackRange(CORDB_ADDRESS * pStart, CORDB_ADDRESS * pEnd)
6826     {
6827         return E_NOTIMPL;
6828     }
6829
6830     //-----------------------------------------------------------
6831     // Non COM methods
6832     //-----------------------------------------------------------
6833
6834     virtual CordbFunction * GetFunction()
6835     {
6836         return NULL;
6837     }
6838
6839     virtual const DT_CONTEXT * GetContext() const;
6840
6841 private:
6842     DT_CONTEXT m_context;
6843 };
6844
6845
6846 class CordbValueEnum : public CordbBase, public ICorDebugValueEnum
6847 {
6848 public:
6849     enum ValueEnumMode {
6850         LOCAL_VARS_ORIGINAL_IL,
6851         LOCAL_VARS_REJIT_IL,
6852         ARGS,
6853     } ;
6854
6855     CordbValueEnum(CordbNativeFrame *frame, ValueEnumMode mode);
6856     HRESULT Init();
6857     ~CordbValueEnum();
6858     virtual void Neuter();
6859
6860 #ifdef _DEBUG
6861     virtual const char * DbgGetName() { return "CordbValueEnum"; }
6862 #endif
6863
6864
6865     //-----------------------------------------------------------
6866     // IUnknown
6867     //-----------------------------------------------------------
6868
6869     ULONG STDMETHODCALLTYPE AddRef()
6870     {
6871         return (BaseAddRef());
6872     }
6873     ULONG STDMETHODCALLTYPE Release()
6874     {
6875         return (BaseRelease());
6876     }
6877     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6878
6879     //-----------------------------------------------------------
6880     // ICorDebugEnum
6881     //-----------------------------------------------------------
6882
6883     COM_METHOD Skip(ULONG celt);
6884     COM_METHOD Reset();
6885     COM_METHOD Clone(ICorDebugEnum **ppEnum);
6886     COM_METHOD GetCount(ULONG *pcelt);
6887
6888     //-----------------------------------------------------------
6889     // ICorDebugValueEnum
6890     //-----------------------------------------------------------
6891
6892     COM_METHOD Next(ULONG celt, ICorDebugValue *values[], ULONG *pceltFetched);
6893
6894 private:
6895     CordbNativeFrame*     m_frame;
6896     ValueEnumMode   m_mode;
6897     UINT            m_iCurrent;
6898     UINT            m_iMax;
6899 };
6900
6901
6902 /* ------------------------------------------------------------------------- *
6903  * Misc Info for the Native Frame class
6904  * ------------------------------------------------------------------------- */
6905
6906 struct CordbMiscFrame
6907 {
6908 public:
6909     CordbMiscFrame();
6910
6911     // new-style constructor
6912     CordbMiscFrame(DebuggerIPCE_JITFuncData * pJITFuncData);
6913
6914 #if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
6915     SIZE_T             parentIP;
6916     FramePointer       fpParentOrSelf;
6917     bool               fIsFilterFunclet;
6918 #endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
6919 };
6920
6921
6922 /* ------------------------------------------------------------------------- *
6923  * Native Frame class
6924  * ------------------------------------------------------------------------- */
6925
6926 class CordbNativeFrame : public CordbFrame, public ICorDebugNativeFrame, public ICorDebugNativeFrame2
6927 {
6928 public:
6929     CordbNativeFrame(CordbThread *        pThread,
6930                      FramePointer         fp,
6931                      CordbNativeCode *    pNativeCode,
6932                      SIZE_T               ip, 
6933                      DebuggerREGDISPLAY * pDRD,
6934                      TADDR                addrAmbientESP,
6935                      bool                 fQuicklyUnwound,
6936                      CordbAppDomain *     pCurrentAppDomain,
6937                      CordbMiscFrame *     pMisc = NULL,
6938                      DT_CONTEXT *         pContext = NULL);
6939     virtual ~CordbNativeFrame();
6940     virtual void Neuter();
6941
6942 #ifdef _DEBUG
6943     virtual const char * DbgGetName() { return "CordbNativeFrame"; }
6944 #endif
6945
6946     //-----------------------------------------------------------
6947     // IUnknown
6948     //-----------------------------------------------------------
6949
6950     ULONG STDMETHODCALLTYPE AddRef()
6951     {
6952         return (BaseAddRef());
6953     }
6954     ULONG STDMETHODCALLTYPE Release()
6955     {
6956         return (BaseRelease());
6957     }
6958     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
6959
6960     //-----------------------------------------------------------
6961     // ICorDebugFrame
6962     //-----------------------------------------------------------
6963
6964     COM_METHOD GetChain(ICorDebugChain **ppChain)
6965     {
6966         return (CordbFrame::GetChain(ppChain));
6967     }
6968     COM_METHOD GetCode(ICorDebugCode **ppCode);
6969     COM_METHOD GetFunction(ICorDebugFunction **ppFunction)
6970     {
6971         return (CordbFrame::GetFunction(ppFunction));
6972     }
6973     COM_METHOD GetFunctionToken(mdMethodDef *pToken)
6974     {
6975         return (CordbFrame::GetFunctionToken(pToken));
6976     }
6977     COM_METHOD GetCaller(ICorDebugFrame **ppFrame)
6978     {
6979         return (CordbFrame::GetCaller(ppFrame));
6980     }
6981     COM_METHOD GetCallee(ICorDebugFrame **ppFrame)
6982     {
6983         return (CordbFrame::GetCallee(ppFrame));
6984     }
6985     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper)
6986     {
6987         return (CordbFrame::CreateStepper(ppStepper));
6988     }
6989
6990     COM_METHOD GetStackRange(CORDB_ADDRESS *pStart, CORDB_ADDRESS *pEnd);
6991
6992     //-----------------------------------------------------------
6993     // ICorDebugNativeFrame
6994     //-----------------------------------------------------------
6995
6996     COM_METHOD GetIP(ULONG32* pnOffset);
6997     COM_METHOD SetIP(ULONG32 nOffset);
6998     COM_METHOD GetRegisterSet(ICorDebugRegisterSet **ppRegisters);
6999     COM_METHOD GetLocalRegisterValue(CorDebugRegister reg,
7000                                      ULONG cbSigBlob,
7001                                      PCCOR_SIGNATURE pvSigBlob,
7002                                      ICorDebugValue ** ppValue);
7003
7004     COM_METHOD GetLocalDoubleRegisterValue(CorDebugRegister highWordReg,
7005                                            CorDebugRegister lowWordReg,
7006                                            ULONG cbSigBlob,
7007                                            PCCOR_SIGNATURE pvSigBlob,
7008                                            ICorDebugValue ** ppValue);
7009
7010     COM_METHOD GetLocalMemoryValue(CORDB_ADDRESS address,
7011                                    ULONG cbSigBlob,
7012                                    PCCOR_SIGNATURE pvSigBlob,
7013                                    ICorDebugValue ** ppValue);
7014
7015     COM_METHOD GetLocalRegisterMemoryValue(CorDebugRegister highWordReg,
7016                                            CORDB_ADDRESS lowWordAddress,
7017                                            ULONG cbSigBlob,
7018                                            PCCOR_SIGNATURE pvSigBlob,
7019                                            ICorDebugValue ** ppValue);
7020
7021     COM_METHOD GetLocalMemoryRegisterValue(CORDB_ADDRESS highWordAddress,
7022                                            CorDebugRegister lowWordRegister,
7023                                            ULONG cbSigBlob,
7024                                            PCCOR_SIGNATURE pvSigBlob,
7025                                            ICorDebugValue ** ppValue);
7026
7027     COM_METHOD CanSetIP(ULONG32 nOffset);
7028
7029     //-----------------------------------------------------------
7030     // ICorDebugNativeFrame2
7031     //-----------------------------------------------------------
7032
7033     COM_METHOD IsChild(BOOL * pIsChild);
7034
7035     COM_METHOD IsMatchingParentFrame(ICorDebugNativeFrame2 *pPotentialParentFrame,
7036                                      BOOL * pIsParent);
7037
7038     COM_METHOD GetStackParameterSize(ULONG32 * pSize);
7039
7040     //-----------------------------------------------------------
7041     // Non-COM members
7042     //-----------------------------------------------------------
7043
7044     // Accessors to return NULL or typesafe cast to derived frame
7045     virtual CordbNativeFrame * GetAsNativeFrame()       { return this; }
7046
7047     CordbFunction * GetFunction();
7048     CordbNativeCode * GetNativeCode();
7049     virtual const DT_CONTEXT * GetContext() const;
7050
7051     // Given the native variable information of a variable, return its value.
7052     // This function assumes that the value is either in a register or on the stack
7053     // (i.e. VLT_REG or VLT_STK).
7054     SIZE_T  GetRegisterOrStackValue(const ICorDebugInfo::NativeVarInfo * pNativeVarInfo);
7055
7056     HRESULT GetLocalRegisterValue(CorDebugRegister reg,
7057                                      CordbType * pType,
7058                                      ICorDebugValue **ppValue);
7059     HRESULT GetLocalDoubleRegisterValue(CorDebugRegister highWordReg,
7060                                            CorDebugRegister lowWordReg,
7061                                            CordbType * pType,
7062                                            ICorDebugValue **ppValue);
7063     HRESULT GetLocalMemoryValue(CORDB_ADDRESS address,
7064                                    CordbType * pType,
7065                                    ICorDebugValue **ppValue);
7066     HRESULT GetLocalByRefMemoryValue(CORDB_ADDRESS address,
7067                                         CordbType * pType,
7068                                         ICorDebugValue **ppValue);
7069     HRESULT GetLocalRegisterMemoryValue(CorDebugRegister highWordReg,
7070                                            CORDB_ADDRESS lowWordAddress,
7071                                            CordbType * pType,
7072                                            ICorDebugValue **ppValue);
7073     HRESULT GetLocalMemoryRegisterValue(CORDB_ADDRESS highWordAddress,
7074                                            CorDebugRegister lowWordRegister,
7075                                            CordbType * pType,
7076                                            ICorDebugValue **ppValue);
7077     UINT_PTR * GetAddressOfRegister(CorDebugRegister regNum) const;
7078     CORDB_ADDRESS GetLeftSideAddressOfRegister(CorDebugRegister regNum) const;
7079 #if !defined(DBG_TARGET_ARM) // @ARMTODO
7080     HRESULT GetLocalFloatingPointValue(DWORD index,
7081                                             CordbType * pType,
7082                                             ICorDebugValue **ppValue);
7083 #endif // !DBG_TARGET_ARM @ARMTODO
7084
7085
7086     CORDB_ADDRESS GetLSStackAddress(ICorDebugInfo::RegNum regNum, signed offset);
7087
7088     bool IsLeafFrame() const;
7089
7090     // Return the offset used for inspection purposes.  
7091     // Refer to the comment at the beginning of the function definition in RsThread.cpp for more information.
7092     SIZE_T GetInspectionIP();
7093     
7094     ULONG32 GetIPOffset();
7095
7096     // whether this is a funclet frame
7097     bool      IsFunclet();
7098     bool      IsFilterFunclet();
7099
7100 #if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
7101     // return the offset of the parent method frame at which an exception occurs
7102     SIZE_T    GetParentIP();
7103 #endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
7104
7105     TADDR GetAmbientESP() { return m_taAmbientESP; }
7106     TADDR GetReturnRegisterValue();
7107
7108     // accessor for the shim private hook code:CordbThread::ConvertFrameForILMethodWithoutMetadata
7109     BOOL ConvertNativeFrameForILMethodWithoutMetadata(ICorDebugInternalFrame2 ** ppInternalFrame2);
7110
7111     //-----------------------------------------------------------
7112     // Data members
7113     //-----------------------------------------------------------
7114
7115 public:
7116     // the register set
7117     DebuggerREGDISPLAY m_rd;
7118
7119     // This field is only true for Enter-Managed chain.  It means that the register set is invalid.
7120     bool               m_quicklyUnwound;
7121
7122     // each CordbNativeFrame corresponds to exactly one CordbJITILFrame and one CordbNativeCode
7123     RSSmartPtr<CordbJITILFrame> m_JITILFrame;
7124     RSSmartPtr<CordbNativeCode> m_nativeCode;
7125
7126     // auxiliary information only used on 64-bit to find the parent stack pointer and offset for funclets
7127     CordbMiscFrame     m_misc;
7128
7129 private:
7130     // the ambient SP value only used on x86 to retrieve sp-relative local variables 
7131     // (most likely in a frameless method)
7132     TADDR    m_taAmbientESP;
7133
7134     // @dbgtodo  inspection - When we DACize the various Cordb*Value classes, we should consider getting rid of the
7135     // DebuggerREGDISPLAY and just use the CONTEXT.  A lot of simplification can be done here.
7136     DT_CONTEXT  m_context;
7137 };
7138
7139
7140 /* ------------------------------------------------------------------------- *
7141  * CordbRegisterSet class
7142  *
7143  * This can be obtained via GetRegisterSet from
7144  *      CordbNativeFrame
7145  *      CordbThread
7146  *
7147  * ------------------------------------------------------------------------- */
7148
7149 #define SETBITULONG64( x ) ( (ULONG64)1 << (x) )
7150 #define SET_BIT_MASK(_mask, _reg)      (_mask[(_reg) >> 3] |=  (1 << ((_reg) & 7)))
7151 #define RESET_BIT_MASK(_mask, _reg)    (_mask[(_reg) >> 3] &= ~(1 << ((_reg) & 7)))
7152 #define IS_SET_BIT_MASK(_mask, _reg)   (_mask[(_reg) >> 3] &   (1 << ((_reg) & 7)))
7153
7154
7155 class CordbRegisterSet : public CordbBase, public ICorDebugRegisterSet, public ICorDebugRegisterSet2
7156 {
7157 public:
7158     CordbRegisterSet(DebuggerREGDISPLAY * pRegDisplay, 
7159                      CordbThread *        pThread,
7160                      bool fActive, 
7161                      bool fQuickUnwind,
7162                      bool fTakeOwnershipOfDRD = false);
7163
7164
7165     ~CordbRegisterSet();
7166
7167
7168
7169     virtual void Neuter();
7170
7171 #ifdef _DEBUG
7172     virtual const char * DbgGetName() { return "CordbRegisterSet"; }
7173 #endif
7174
7175     //-----------------------------------------------------------
7176     // IUnknown
7177     //-----------------------------------------------------------
7178
7179     ULONG STDMETHODCALLTYPE AddRef()
7180     {
7181         return (BaseAddRefEnforceExternal());
7182     }
7183     ULONG STDMETHODCALLTYPE Release()
7184     {
7185         return (BaseReleaseEnforceExternal());
7186     }
7187
7188     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7189
7190
7191
7192     //-----------------------------------------------------------
7193     // ICorDebugRegisterSet
7194     // More extensive explanation are in Src/inc/CorDebug.idl
7195     //-----------------------------------------------------------
7196     COM_METHOD GetRegistersAvailable(ULONG64 *pAvailable);
7197
7198     COM_METHOD GetRegisters(ULONG64 mask,
7199                             ULONG32 regCount,
7200                             CORDB_REGISTER regBuffer[]);
7201     COM_METHOD SetRegisters( ULONG64 mask,
7202                              ULONG32 regCount,
7203                              CORDB_REGISTER regBuffer[])
7204     {
7205         LIMITED_METHOD_CONTRACT;
7206
7207         VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER,
7208                                          regCount, true, true);
7209
7210         return E_NOTIMPL;
7211     }
7212
7213     COM_METHOD GetThreadContext(ULONG32 contextSize, BYTE context[]);
7214
7215     // SetThreadContexthad a very problematic implementation in v1.1.
7216     // We've ripped it out in V2.0 and E_NOTIMPL it. See V1.1 sources for what it used to look like
7217     // in case we ever want to re-add it.
7218     // If we ever re-implement it consider the following:
7219     // - must fail on non-leaf frames (just check m_active).
7220     // - must make sure that GetThreadContext() is fully accurate. If we don't have SetThCtx, then
7221     //   GetThreadCtx bugs are much more benign.
7222     // - be sure to update any shared reg displays (what if a frame + chain have the same rd) and
7223     //   also update any cached contexts (such as CordbThread::m_context).
7224     // - be sure to honor the context flags and only setting what we can set.
7225     //
7226     // Friday, July 16, 2004. (This date will be useful for Source control history)
7227     COM_METHOD SetThreadContext(ULONG32 contextSize, BYTE context[])
7228     {
7229         return E_NOTIMPL;
7230     }
7231
7232     //-----------------------------------------------------------
7233     // ICorDebugRegisterSet2
7234     // More extensive explanation are in Src/inc/CorDebug.idl
7235     //-----------------------------------------------------------
7236     COM_METHOD GetRegistersAvailable(ULONG32 regCount,
7237                                      BYTE    pAvailable[]);
7238
7239     COM_METHOD GetRegisters(ULONG32 maskCount,
7240                             BYTE    mask[],
7241                             ULONG32 regCount,
7242                             CORDB_REGISTER regBuffer[]);
7243
7244     COM_METHOD SetRegisters(ULONG32 maskCount,
7245                             BYTE    mask[],
7246                             ULONG32 regCount,
7247                             CORDB_REGISTER regBuffer[])
7248     {
7249         LIMITED_METHOD_CONTRACT;
7250
7251         VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER,
7252                                          regCount, true, true);
7253
7254         return E_NOTIMPL;
7255     }
7256
7257 protected:
7258     // Platform specific helper for GetThreadContext.
7259     void InternalCopyRDToContext(DT_CONTEXT * pContext);
7260
7261     // Adapters to impl v2.0 interfaces on top of v1.0 interfaces.
7262     HRESULT GetRegistersAvailableAdapter(ULONG32 regCount, BYTE pAvailable[]);
7263     HRESULT GetRegistersAdapter(ULONG32 maskCount, BYTE mask[], ULONG32 regCount, CORDB_REGISTER regBuffer[]);
7264
7265
7266     // This CordbRegisterSet is responsible to free this memory if m_fTakeOwnershipOfDRD is true.  Otherwise,
7267     // this memory is freed by the CordbNativeFrame or CordbThread which creates this CordbRegisterSet.
7268     DebuggerREGDISPLAY  *m_rd;
7269     CordbThread         *m_thread;
7270     bool                m_active; // true if we're the leafmost register set.
7271     bool                m_quickUnwind;
7272
7273     // true if the CordbRegisterSet owns the DebuggerREGDISPLAY pointer and needs to free the memory
7274     bool                m_fTakeOwnershipOfDRD;      
7275 } ;
7276
7277
7278
7279
7280 /* ------------------------------------------------------------------------- *
7281  * JIT-IL Frame class
7282  * ------------------------------------------------------------------------- */
7283
7284 class CordbJITILFrame : public CordbBase, public ICorDebugILFrame, public ICorDebugILFrame2, public ICorDebugILFrame3, public ICorDebugILFrame4
7285 {
7286 public:
7287     CordbJITILFrame(CordbNativeFrame *    pNativeFrame,
7288                     CordbILCode *         pCode,
7289                     UINT_PTR              ip,
7290                     CorDebugMappingResult mapping,
7291                     GENERICS_TYPE_TOKEN   exactGenericArgsToken,
7292                     DWORD                 dwExactGenericArgsTokenIndex,
7293                     bool                  fVarArgFnx,
7294                     CordbReJitILCode *    pReJitCode);
7295     HRESULT Init();
7296     virtual ~CordbJITILFrame();
7297     virtual void Neuter();
7298
7299
7300 #ifdef _DEBUG
7301     virtual const char * DbgGetName() { return "CordbJITILFrame"; }
7302 #endif
7303
7304     //-----------------------------------------------------------
7305     // IUnknown
7306     //-----------------------------------------------------------
7307
7308     ULONG STDMETHODCALLTYPE AddRef()
7309     {
7310         return (BaseAddRef());
7311     }
7312     ULONG STDMETHODCALLTYPE Release()
7313     {
7314         return (BaseRelease());
7315     }
7316     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7317
7318     //-----------------------------------------------------------
7319     // ICorDebugFrame
7320     //-----------------------------------------------------------
7321
7322     COM_METHOD GetChain(ICorDebugChain **ppChain);
7323     COM_METHOD GetCode(ICorDebugCode **ppCode);
7324     COM_METHOD GetFunction(ICorDebugFunction **ppFunction);
7325     COM_METHOD GetFunctionToken(mdMethodDef *pToken);
7326     COM_METHOD GetStackRange(CORDB_ADDRESS *pStart, CORDB_ADDRESS *pEnd);
7327     COM_METHOD CreateStepper(ICorDebugStepper **ppStepper);
7328     COM_METHOD GetCaller(ICorDebugFrame **ppFrame);
7329     COM_METHOD GetCallee(ICorDebugFrame **ppFrame);
7330
7331     //-----------------------------------------------------------
7332     // ICorDebugILFrame
7333     //-----------------------------------------------------------
7334
7335     COM_METHOD GetIP(ULONG32* pnOffset, CorDebugMappingResult *pMappingResult);
7336     COM_METHOD SetIP(ULONG32 nOffset);
7337     COM_METHOD EnumerateLocalVariables(ICorDebugValueEnum **ppValueEnum);
7338     COM_METHOD GetLocalVariable(DWORD dwIndex, ICorDebugValue **ppValue);
7339     COM_METHOD EnumerateArguments(ICorDebugValueEnum **ppValueEnum);
7340     COM_METHOD GetArgument(DWORD dwIndex, ICorDebugValue ** ppValue);
7341     COM_METHOD GetStackDepth(ULONG32 *pDepth);
7342     COM_METHOD GetStackValue(DWORD dwIndex, ICorDebugValue **ppValue);
7343     COM_METHOD CanSetIP(ULONG32 nOffset);
7344
7345     //-----------------------------------------------------------
7346     // ICorDebugILFrame2
7347     //-----------------------------------------------------------
7348
7349     // Called at an EnC remap opportunity to remap to the latest version of a function
7350     COM_METHOD RemapFunction(ULONG32 nOffset);
7351
7352     COM_METHOD EnumerateTypeParameters(ICorDebugTypeEnum **ppTyParEnum);
7353     
7354     //-----------------------------------------------------------
7355     // ICorDebugILFrame3
7356     //-----------------------------------------------------------
7357     
7358     COM_METHOD GetReturnValueForILOffset(ULONG32 ILoffset, ICorDebugValue** ppReturnValue);
7359
7360     //-----------------------------------------------------------
7361     // ICorDebugILFrame4
7362     //-----------------------------------------------------------
7363
7364     COM_METHOD EnumerateLocalVariablesEx(ILCodeKind flags, ICorDebugValueEnum **ppValueEnum);
7365     COM_METHOD GetLocalVariableEx(ILCodeKind flags, DWORD dwIndex, ICorDebugValue **ppValue);
7366     COM_METHOD GetCodeEx(ILCodeKind flags, ICorDebugCode **ppCode);
7367
7368     //-----------------------------------------------------------
7369     // Non-COM methods
7370     //-----------------------------------------------------------
7371
7372     CordbModule *GetModule();
7373
7374     HRESULT GetNativeVariable(CordbType *type,
7375                               const ICorDebugInfo::NativeVarInfo *pNativeVarInfo,
7376                               ICorDebugValue **ppValue);
7377
7378     CordbAppDomain *GetCurrentAppDomain();
7379
7380     CordbFunction *GetFunction();
7381
7382     // ILVariableToNative serves to let the frame intercept accesses
7383     // to var args variables.
7384     HRESULT ILVariableToNative(DWORD dwIndex,
7385                                const ICorDebugInfo::NativeVarInfo ** ppNativeInfo);
7386
7387     // Fills in our array of var args variables
7388     HRESULT FabricateNativeInfo(DWORD dwIndex,
7389                                 const ICorDebugInfo::NativeVarInfo ** ppNativeInfo);
7390
7391     HRESULT GetArgumentType(DWORD dwIndex,
7392                             CordbType ** ppResultType);
7393
7394     // load the generics type and method arguments into a cache
7395     void LoadGenericArgs();
7396
7397     HRESULT QueryInterfaceInternal(REFIID id, void** pInterface);
7398
7399     // Builds an generic Instaniation object from the mdClass and generic signature
7400     // for what we are calling into.
7401     static HRESULT BuildInstantiationForCallsite(CordbModule *pModule, NewArrayHolder<CordbType*> &types, Instantiation &inst, Instantiation *currentInstantiation, mdToken targetClass, SigParser funcGenerics);
7402
7403     CordbILCode* GetOriginalILCode();
7404     CordbReJitILCode* GetReJitILCode();
7405
7406 private:
7407     void    RefreshCachedVarArgSigParserIfNeeded();
7408
7409     // Worker function for GetReturnValueForILOffset.
7410     HRESULT GetReturnValueForILOffsetImpl(ULONG32 ILoffset, ICorDebugValue** ppReturnValue);
7411
7412     // Given pType, fills ppReturnValue with the correct value.
7413     HRESULT GetReturnValueForType(CordbType *pType, ICorDebugValue **ppReturnValue);
7414
7415     //-----------------------------------------------------------
7416     // Data members
7417     //-----------------------------------------------------------
7418
7419 public:
7420     // each CordbJITILFrame corresponds to exactly one CordbNativeFrame and one CordbILCode
7421     CordbNativeFrame * m_nativeFrame;
7422     CordbILCode *      m_ilCode;
7423
7424     // the IL offset and the mapping result for the offset
7425     UINT_PTR          m_ip;
7426     CorDebugMappingResult m_mapping;
7427
7428     // <vararg-specific fields>
7429
7430     // whether this is a vararg function
7431     bool              m_fVarArgFnx;
7432
7433     // the number of arguments, including the var args
7434     ULONG             m_allArgsCount;
7435
7436     // This byte array is used to store the signature for vararg methods.
7437     // It points to the underlying memory used by m_sigParserCached, and it enables us to easily delete
7438     // the underlying memory when the CordbJITILFrame is neutered.
7439     BYTE *            m_rgbSigParserBuf;
7440     
7441     // Do not mutate this, instead make copies of it and use the copies, that way we are guaranteed to 
7442     // start at the correct position in the signature each time.  
7443     // The underlying memory used for the signature in the SigParser must not be in the DAC cache.
7444     // Otherwise it may be flushed underneath us, and we would AV when we try to access it.
7445     SigParser         m_sigParserCached;
7446
7447     // the address of the first arg; only used for vararg functions
7448     CORDB_ADDRESS     m_FirstArgAddr;
7449
7450     // This is an array of variable information for the arguments.  
7451     // The variable information is fabricated by the RS.
7452     ICorDebugInfo::NativeVarInfo * m_rgNVI;
7453
7454     // </vararg-specific fields>
7455
7456     Instantiation     m_genericArgs;        // the generics type arguments
7457     BOOL              m_genericArgsLoaded;  // whether we have loaded and cached the generics type arguments
7458
7459     // An extra token to help fetch information about any generic
7460     // parameters passed to the method, perhaps dynamically.
7461     // This is the so-called generics type context/token.
7462     //
7463     // This token comes from the stackwalker and it may be NULL, in which case we need to retrieve the token 
7464     // ourselves using m_dwFrameParamsTokenIndex and the variable lifetime information.
7465     GENERICS_TYPE_TOKEN m_frameParamsToken;
7466
7467     // IL Variable index of the Generics Arg Token.
7468     DWORD               m_dwFrameParamsTokenIndex;
7469
7470     // if this frame is instrumented with rejit, this will point to the instrumented IL code
7471     RSSmartPtr<CordbReJitILCode> m_pReJitCode;
7472 };
7473
7474 /* ------------------------------------------------------------------------- *
7475  * Breakpoint class
7476  * ------------------------------------------------------------------------- */
7477
7478 enum CordbBreakpointType
7479 {
7480     CBT_FUNCTION,
7481     CBT_MODULE,
7482     CBT_VALUE
7483 };
7484
7485 class CordbBreakpoint : public CordbBase, public ICorDebugBreakpoint
7486 {
7487 public:
7488     CordbBreakpoint(CordbProcess * pProcess, CordbBreakpointType bpType);
7489     virtual void Neuter();
7490
7491 #ifdef _DEBUG
7492     virtual const char * DbgGetName() { return "CordbBreakpoint"; }
7493 #endif
7494
7495     //-----------------------------------------------------------
7496     // IUnknown
7497     //-----------------------------------------------------------
7498
7499     ULONG STDMETHODCALLTYPE AddRef()
7500     {
7501         return (BaseAddRef());
7502     }
7503     ULONG STDMETHODCALLTYPE Release()
7504     {
7505         return (BaseRelease());
7506     }
7507     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7508
7509     //-----------------------------------------------------------
7510     // ICorDebugBreakpoint
7511     //-----------------------------------------------------------
7512
7513     COM_METHOD BaseIsActive(BOOL *pbActive);
7514
7515     //-----------------------------------------------------------
7516     // Non-COM methods
7517     //-----------------------------------------------------------
7518     CordbBreakpointType GetBPType()
7519     {
7520         return m_type;
7521     }
7522
7523     virtual void Disconnect() {}
7524
7525     CordbAppDomain *GetAppDomain()
7526     {
7527         return m_pAppDomain;
7528     }
7529     //-----------------------------------------------------------
7530     // Data members
7531     //-----------------------------------------------------------
7532
7533 public:
7534     bool                m_active;
7535     CordbAppDomain *m_pAppDomain;
7536     CordbBreakpointType m_type;
7537 };
7538
7539 /* ------------------------------------------------------------------------- *
7540  * Function Breakpoint class
7541  * ------------------------------------------------------------------------- */
7542
7543 class CordbFunctionBreakpoint : public CordbBreakpoint,
7544                                 public ICorDebugFunctionBreakpoint
7545 {
7546 public:
7547     CordbFunctionBreakpoint(CordbCode *code, SIZE_T offset);
7548     ~CordbFunctionBreakpoint();
7549
7550     virtual void Neuter();
7551 #ifdef _DEBUG
7552     virtual const char * DbgGetName() { return "CordbFunctionBreakpoint"; }
7553 #endif
7554
7555
7556     //-----------------------------------------------------------
7557     // IUnknown
7558     //-----------------------------------------------------------
7559
7560     ULONG STDMETHODCALLTYPE AddRef()
7561     {
7562         return (BaseAddRef());
7563     }
7564     ULONG STDMETHODCALLTYPE Release()
7565     {
7566         return (BaseRelease());
7567     }
7568     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7569
7570     //-----------------------------------------------------------
7571     // ICorDebugBreakpoint
7572     //-----------------------------------------------------------
7573
7574     COM_METHOD GetFunction(ICorDebugFunction **ppFunction);
7575     COM_METHOD GetOffset(ULONG32 *pnOffset);
7576     COM_METHOD Activate(BOOL bActive);
7577     COM_METHOD IsActive(BOOL *pbActive)
7578     {
7579         VALIDATE_POINTER_TO_OBJECT(pbActive, BOOL *);
7580
7581         return BaseIsActive(pbActive);
7582     }
7583
7584     //-----------------------------------------------------------
7585     // Non-COM methods
7586     //-----------------------------------------------------------
7587
7588     void Disconnect();
7589
7590     //-----------------------------------------------------------
7591     // Convenience routines
7592     //-----------------------------------------------------------
7593
7594
7595     //-----------------------------------------------------------
7596     // Data members
7597     //-----------------------------------------------------------
7598
7599     // Get a point to the LS BP object.
7600     LSPTR_BREAKPOINT GetLsPtrBP();
7601 public:
7602
7603     // We need to have a strong pointer because we may access the m_code object after we're neutered.
7604     // @todo - use external pointer b/c Breakpoints aren't yet rooted, and so this reference could be
7605     // leaked.
7606     RSExtSmartPtr<CordbCode> m_code;
7607     SIZE_T          m_offset;
7608 };
7609
7610 /* ------------------------------------------------------------------------- *
7611  * Module Breakpoint class
7612  * ------------------------------------------------------------------------- */
7613
7614 class CordbModuleBreakpoint : public CordbBreakpoint,
7615                               public ICorDebugModuleBreakpoint
7616 {
7617 public:
7618     CordbModuleBreakpoint(CordbModule *pModule);
7619
7620
7621
7622 #ifdef _DEBUG
7623     virtual const char * DbgGetName() { return "CordbModuleBreakpoint"; }
7624 #endif
7625
7626
7627     //-----------------------------------------------------------
7628     // IUnknown
7629     //-----------------------------------------------------------
7630
7631     ULONG STDMETHODCALLTYPE AddRef()
7632     {
7633         return (BaseAddRef());
7634     }
7635     ULONG STDMETHODCALLTYPE Release()
7636     {
7637         return (BaseRelease());
7638     }
7639     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7640
7641     //-----------------------------------------------------------
7642     // ICorDebugModuleBreakpoint
7643     //-----------------------------------------------------------
7644
7645     COM_METHOD GetModule(ICorDebugModule **ppModule);
7646     COM_METHOD Activate(BOOL bActive);
7647     COM_METHOD IsActive(BOOL *pbActive)
7648     {
7649         VALIDATE_POINTER_TO_OBJECT(pbActive, BOOL *);
7650
7651         return BaseIsActive(pbActive);
7652     }
7653
7654     //-----------------------------------------------------------
7655     // Non-COM methods
7656     //-----------------------------------------------------------
7657
7658     void Disconnect();
7659
7660 public:
7661     CordbModule       *m_module;
7662 };
7663
7664
7665 /* ------------------------------------------------------------------------- *
7666  * Stepper class
7667  * ------------------------------------------------------------------------- */
7668
7669 class CordbStepper : public CordbBase, public ICorDebugStepper, public ICorDebugStepper2
7670 {
7671 public:
7672     CordbStepper(CordbThread *thread, CordbFrame *frame = NULL);
7673
7674
7675
7676 #ifdef _DEBUG
7677     virtual const char * DbgGetName() { return "CordbStepper"; }
7678 #endif
7679
7680
7681     //-----------------------------------------------------------
7682     // IUnknown
7683     //-----------------------------------------------------------
7684
7685     ULONG STDMETHODCALLTYPE AddRef()
7686     {
7687         return (BaseAddRef());
7688     }
7689     ULONG STDMETHODCALLTYPE Release()
7690     {
7691         return (BaseRelease());
7692     }
7693     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
7694
7695     //-----------------------------------------------------------
7696     // ICorDebugStepper
7697     //-----------------------------------------------------------
7698
7699     COM_METHOD IsActive(BOOL *pbActive);
7700     COM_METHOD Deactivate();
7701     COM_METHOD SetInterceptMask(CorDebugIntercept mask);
7702     COM_METHOD SetUnmappedStopMask(CorDebugUnmappedStop mask);
7703     COM_METHOD Step(BOOL bStepIn);
7704     COM_METHOD StepRange(BOOL bStepIn,
7705                          COR_DEBUG_STEP_RANGE ranges[],
7706                          ULONG32 cRangeCount);
7707     COM_METHOD StepOut();
7708     COM_METHOD SetRangeIL(BOOL bIL);
7709
7710     //-----------------------------------------------------------
7711     // ICorDebugStepper2
7712     //-----------------------------------------------------------
7713     COM_METHOD SetJMC(BOOL fIsJMCStepper);
7714
7715     //-----------------------------------------------------------
7716     // Convenience routines
7717     //-----------------------------------------------------------
7718
7719     CordbAppDomain *GetAppDomain()
7720     {
7721         return (m_thread->GetAppDomain());
7722     }
7723
7724     LSPTR_STEPPER GetLsPtrStepper();
7725
7726     //-----------------------------------------------------------
7727     // Data members
7728     //-----------------------------------------------------------
7729
7730     CordbThread     *m_thread;
7731     CordbFrame      *m_frame;
7732     REMOTE_PTR      m_stepperToken;
7733     bool            m_active;
7734     bool            m_rangeIL;
7735     bool            m_fIsJMCStepper;
7736     CorDebugUnmappedStop m_rgfMappingStop;
7737     CorDebugIntercept m_rgfInterceptStop;
7738 };
7739
7740 #define REG_SIZE sizeof(SIZE_T)
7741
7742 // class RegisterInfo: encapsulates information necessary to identify and access a specific register in a
7743 // register display
7744 class RegisterInfo
7745
7746 public:
7747     // constructor for an instance of RegisterInfo
7748     // Arguments:
7749     //     input:  kNumber - value from CorDebugRegister to identify the register
7750     //             addr    - address in remote register display that holds the value
7751     //     output: no out parameters, but this instance of RegisterInfo has been initialized
7752     RegisterInfo(const CorDebugRegister kNumber, CORDB_ADDRESS addr, SIZE_T value):       
7753         m_kRegNumber((CorDebugRegister)kNumber),
7754         m_regAddr(addr),
7755         m_regValue(value)
7756     {};
7757
7758
7759     // copy constructor
7760     // Arguments:
7761     //     input:  regInfo - register info from which the values for this instance will come
7762     //     output: no out parameters, but this instance of RegisterInfo has been initialized
7763     RegisterInfo(const RegisterInfo * pRegInfo):
7764         m_kRegNumber(pRegInfo->m_kRegNumber),
7765         m_regAddr(pRegInfo->m_regAddr),
7766         m_regValue(pRegInfo->m_regValue)
7767     {};
7768
7769
7770     //-------------------------------------
7771     // data members
7772     //-------------------------------------    
7773
7774     // enumeration value to identify the register, e.g., REGISTER_X86_EAX, or REGISTER_AMD64_XMM0
7775     CorDebugRegister  m_kRegNumber;
7776
7777     // address in a context or frame register display of the register value
7778     CORDB_ADDRESS     m_regAddr;
7779
7780     // the actual value of the register
7781     SIZE_T            m_regValue;
7782 }; // class RegisterInfo
7783
7784 // class EnregisteredValueHome: abstract class to encapsulate basic information for a register value, and
7785 // serve as a base class for values residing in register-based locations, such as a single register, a
7786 // register pair, or a register and memory location.
7787 class EnregisteredValueHome
7788 {
7789 public:
7790
7791     // constructor to initialize an instance of EnregisteredValueHome
7792     EnregisteredValueHome(const CordbNativeFrame * pFrame);
7793
7794     // virtual "copy constructor" to make a copy of "this" to be owned by a different instance of
7795     // Cordb*Value. If an instance of CordbVCObjectValue represents an enregistered value class, it means
7796     // there is a single field. This implies that the register for the CordbVCObject instance is the same as
7797     // the register for its field. When we create a Cordb*Value to represent this field, we need to make a
7798     // copy of the EnregisteredValueHome belonging to the CordbVCObject instance to become the
7799     // EnregisteredValueHome of the Cord*Value representing the field.
7800     // returns:
7801     //   a new cloned copy of this object, allocated on the heap.
7802     //   Caller is responsible for deleting the  memory (using the standard delete operator).
7803     // note:
7804     //    C++ allows derived implementations to differ on return type, thus allowing
7805     //    derived impls to return the cloned copy as its actual derived type, and not just as a base type.
7806
7807
7808
7809     virtual
7810     EnregisteredValueHome * Clone() const = 0;
7811
7812     // set a remote enregistered location to a new value
7813     // Arguments:
7814     //     input:  pNewValue - buffer containing the new value along with its size
7815     //             pContext  - context from which the value comes
7816     //             fIsSigned - indicates whether the value is signed or not. The value provided may be smaller than
7817     //                         a register, in which case we'll need to extend it to a full register width. To do this
7818     //                         correctly, we need to know whether to sign extend or zero extend. Currently, only
7819     //                         the RegValueHome virtual function uses this, but we may need it if we introduce
7820     //                         types that don't completely occupy the size of two registers.  
7821     //     output: updates the remote enregistered value on success            
7822     // Note: Throws E_FAIL for invalid input or various HRESULTs from an 
7823     //                         unsuccessful call to WriteProcessMemory
7824     virtual
7825     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned) = 0;
7826
7827     // Gets an enregistered value and returns it to the caller
7828     // Arguments: 
7829     //     input:  pValueOutBuffer - buffer in which to return the value, along with its size
7830     //     output: pValueOutBuffer - filled with the value 
7831     // Note: Throws E_NOTIMPL for attempts to get an enregistered value for a float register
7832     // (implementation for derived class FloatRegValueHome)
7833     virtual
7834     void GetEnregisteredValue(MemoryRange valueOutBuffer) = 0;
7835
7836     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
7837     // instance of a derived class of EnregisteredValueHome
7838     // Arguments: input:  none--uses fields of "this"
7839     //            output: pRegAddr - address of an instance of RemoteAddress with field values set to corresponding 
7840     //            field values of "this"
7841     virtual
7842     void CopyToIPCEType(RemoteAddress * pRegAddr) = 0;
7843
7844     // accessor
7845     const CordbNativeFrame * GetFrame() const { return m_pFrame; };
7846
7847     //-------------------------------------
7848     // data members
7849     //------------------------------------- 
7850 protected:    
7851     // The frame on which the value resides
7852     const CordbNativeFrame * m_pFrame;
7853
7854 }; // class EnregisteredValueHome
7855
7856 typedef NewHolder<EnregisteredValueHome> EnregisteredValueHomeHolder;
7857
7858 // class RegValueHome: encapsulates basic information for a value that resides in a single register
7859 // and serves as a base class for values residing in a register pair.
7860 class RegValueHome: public EnregisteredValueHome
7861 {
7862 public:
7863
7864     // initializing constructor 
7865     // Arguments:
7866     //     input:  pFrame  - frame to which the value belongs
7867     //             regNum  - enumeration value corresponding to the particular hardware register in
7868     //                       which the value resides
7869     //             regAddr - remote address within a register display (in a context or frame) of the
7870     //                       register value
7871     //     output: no out parameters, but the instance has been initialized
7872     RegValueHome(const CordbNativeFrame *  pFrame, 
7873                  CorDebugRegister          regNum):
7874         EnregisteredValueHome(pFrame),
7875         m_reg1Info(regNum, 
7876                    pFrame->GetLeftSideAddressOfRegister(regNum), 
7877                    *(pFrame->GetAddressOfRegister(regNum)))
7878     {};
7879
7880     // copy constructor
7881     // Arguments:
7882     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
7883     //                              instance will come
7884     //     output: no out parameters, but the instance has been initialized
7885     RegValueHome(const RegValueHome * pRemoteRegAddr):
7886         EnregisteredValueHome(pRemoteRegAddr->m_pFrame),
7887         m_reg1Info(pRemoteRegAddr->m_reg1Info)
7888     {};
7889
7890     // make a copy of this instance of RegValueHome
7891     virtual
7892     RegValueHome * Clone() const { return new RegValueHome(*this); };
7893
7894     // updates a register in a given context, and in the regdisplay of a given frame.
7895     void SetContextRegister(DT_CONTEXT *     pContext,
7896                             CorDebugRegister regNum,
7897                             SIZE_T           newVal);
7898
7899     // set the value of a remote enregistered value
7900     virtual
7901     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
7902
7903     // Gets an enregistered value and returns it to the caller
7904     virtual
7905     void GetEnregisteredValue(MemoryRange valueOutBuffer);
7906     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
7907     // instance of a derived class of RegValueHome
7908     virtual
7909     void CopyToIPCEType(RemoteAddress * pRegAddr);
7910
7911     //-------------------------------------
7912     // data members
7913     //------------------------------------- 
7914 protected:       
7915     // The information for the register in which the value resides. 
7916     const RegisterInfo               m_reg1Info;
7917 }; // class RegValueHome
7918
7919 // class RegRegValueHome
7920 // derived class to add a second register for values that live in a pair of registers
7921 class RegRegValueHome: public RegValueHome
7922 {
7923 public:
7924     // initializing constructor 
7925     // Arguments:
7926     //     input:  pFrame   - frame to which the value belongs
7927     //             reg1Num  - enumeration value corresponding to the first particular hardware register in
7928     //                        which the value resides
7929     //             reg1Addr - remote address within a register display (in a context or frame) of the
7930     //                        first register
7931     //             reg2Num  - enumeration value corresponding to the second particular hardware register in
7932     //                        which the value resides
7933     //             reg2Addr - remote address within a register display (in a context or frame) of the
7934     //                        second register
7935     //     output: no out parameters, but the instance has been initialized
7936     RegRegValueHome(const CordbNativeFrame * pFrame, 
7937                     CorDebugRegister         reg1Num, 
7938                     CorDebugRegister         reg2Num):
7939         RegValueHome(pFrame, reg1Num),
7940         m_reg2Info(reg2Num, 
7941                    pFrame->GetLeftSideAddressOfRegister(reg2Num),
7942                    *(pFrame->GetAddressOfRegister(reg2Num)))
7943     {};
7944
7945     // copy constructor
7946     // Arguments:
7947     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
7948     //                              instance will come
7949     //     output: no out parameters, but the instance has been initialized
7950     RegRegValueHome(const RegRegValueHome * pRemoteRegAddr):
7951         RegValueHome(pRemoteRegAddr),
7952         m_reg2Info(pRemoteRegAddr->m_reg2Info)
7953     {};
7954
7955     // make a copy of this instance of RegRegValueHome
7956     virtual
7957     RegRegValueHome * Clone() const { return new RegRegValueHome(*this); };
7958
7959     // set the value of a remote enregistered value
7960     virtual
7961     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
7962
7963     // Gets an enregistered value and returns it to the caller
7964     virtual
7965     void GetEnregisteredValue(MemoryRange valueOutBuffer);
7966
7967     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
7968     // instance of a derived class of EnregisteredValueHome
7969     void CopyToIPCEType(RemoteAddress * pRegAddr);
7970
7971     //-------------------------------------
7972     // data members
7973     //------------------------------------- 
7974     
7975 protected:    
7976     // The information for the second of two registers in which the value resides. 
7977     const RegisterInfo               m_reg2Info;
7978 }; // class RegRegValueHome
7979
7980 // class RegAndMemBaseValueHome 
7981 // derived from RegValueHome, this class is also a base class for RegMemValueHome
7982 // and MemRegValueHome, which add a memory location for reg-mem or mem-reg values
7983 class RegAndMemBaseValueHome: public RegValueHome
7984 {
7985 public:
7986     // initializing constructor 
7987     // Arguments:
7988     //     input:  pFrame   - frame to which the value belongs
7989     //             reg1Num  - enumeration value corresponding to the first particular hardware register in
7990     //                        which the value resides
7991     //             reg1Addr - remote address within a register display (in a context or frame) of the
7992     //                        register component of the value
7993     //             memAddr  - remote address for the memory component of the value
7994     //     output: no out parameters, but the instance has been initialized
7995     RegAndMemBaseValueHome(const CordbNativeFrame *      pFrame, 
7996                            CorDebugRegister              reg1Num, 
7997                            CORDB_ADDRESS                 memAddr):
7998         RegValueHome(pFrame, reg1Num),
7999         m_memAddr(memAddr) 
8000     {};
8001
8002     // copy constructor
8003     // Arguments:
8004     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
8005     //                              instance will come
8006     //     output: no out parameters, but the instance has been initialized
8007     RegAndMemBaseValueHome(const RegAndMemBaseValueHome * pRemoteRegAddr):
8008         RegValueHome(pRemoteRegAddr), 
8009         m_memAddr()
8010     {};
8011
8012     // make a copy of this instance of RegRegValueHome
8013     virtual
8014     RegAndMemBaseValueHome * Clone() const = 0;
8015
8016     // set the value of a remote enregistered value
8017     virtual
8018     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * DT_pContext, bool fIsSigned) = 0;
8019
8020     // Gets an enregistered value and returns it to the caller
8021     virtual 
8022     void GetEnregisteredValue(MemoryRange valueOutBuffer) = 0;
8023
8024     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
8025     // instance of a derived class of EnregisteredValueHome
8026     virtual
8027     void CopyToIPCEType(RemoteAddress * pRegAddr) = 0;
8028
8029     //-------------------------------------
8030     // data members
8031     //------------------------------------- 
8032     
8033 protected:    
8034     // remote address for the memory component of the value
8035     CORDB_ADDRESS m_memAddr;
8036
8037 }; // class RegAndMemBaseValueHome;
8038
8039 // class RegMemValueHome
8040 // type derived from abstract class RegAndMemBaseValueHome to represent a Register/Memory location where the 
8041 // high order part of the value is kept in a register, and the low order part is kept in memory
8042 class RegMemValueHome: public RegAndMemBaseValueHome
8043 {
8044 public:
8045
8046     // initializing constructor 
8047     // Arguments:
8048     //     input:  pFrame   - frame to which the value belongs
8049     //             reg1Num  - enumeration value corresponding to the first particular hardware register in
8050     //                        which the value resides
8051     //             reg1Addr - remote address within a register display (in a context or frame) of the
8052     //                        register component of the value
8053     //             memAddr  - remote address for the memory component of the value
8054     //     output: no out parameters, but the instance has been initialized
8055     RegMemValueHome(const CordbNativeFrame *      pFrame, 
8056                     CorDebugRegister              reg1Num, 
8057                     CORDB_ADDRESS                 memAddr):
8058        RegAndMemBaseValueHome(pFrame, reg1Num, memAddr)
8059    {};
8060
8061     // copy constructor
8062     // Arguments:
8063     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
8064     //                              instance will come
8065     //     output: no out parameters, but the instance has been initialized
8066     RegMemValueHome(const RegMemValueHome * pRemoteRegAddr):
8067         RegAndMemBaseValueHome(pRemoteRegAddr)
8068     {};
8069
8070     // make a copy of this instance of RegMemValueHome
8071     virtual
8072     RegMemValueHome * Clone() const { return new RegMemValueHome(*this); };
8073
8074     // set the value of a remote enregistered value
8075     virtual
8076     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
8077
8078     // Gets an enregistered value and returns it to the caller
8079     virtual
8080     void GetEnregisteredValue(MemoryRange valueOutBuffer);
8081
8082     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
8083     // instance of a derived class of EnregisteredValueHome
8084     virtual
8085     void CopyToIPCEType(RemoteAddress * pRegAddr);
8086
8087 }; // class RegMemValueHome;
8088
8089 // class MemRegValueHome
8090 // type derived from abstract class RegAndMemBaseValueHome to represent a Register/Memory location where the 
8091 // low order part of the value is kept in a register, and the high order part is kept in memory
8092 class MemRegValueHome: public RegAndMemBaseValueHome
8093 {
8094 public:
8095
8096     // initializing constructor 
8097     // Arguments:
8098     //     input:  pFrame   - frame to which the value belongs
8099     //             reg1Num  - enumeration value corresponding to the first particular hardware register in
8100     //                        which the value resides
8101     //             reg1Addr - remote address within a register display (in a context or frame) of the
8102     //                        register component of the value
8103     //             memAddr  - remote address for the memory component of the value
8104     //     output: no out parameters, but the instance has been initialized
8105     MemRegValueHome(const CordbNativeFrame *      pFrame, 
8106                     CorDebugRegister              reg1Num, 
8107                     CORDB_ADDRESS                 memAddr):
8108        RegAndMemBaseValueHome(pFrame, reg1Num, memAddr)
8109    {};
8110
8111     // copy constructor
8112     // Arguments:
8113     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
8114     //                              instance will come
8115     //     output: no out parameters, but the instance has been initialized
8116     MemRegValueHome(const MemRegValueHome * pRemoteRegAddr):
8117         RegAndMemBaseValueHome(pRemoteRegAddr)
8118     {};
8119
8120     // make a copy of this instance of MemRegValueHome
8121     virtual
8122     MemRegValueHome * Clone() const { return new MemRegValueHome(*this); };
8123
8124     // set the value of a remote enregistered value
8125     virtual
8126     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
8127
8128     // Gets an enregistered value and returns it to the caller
8129     virtual
8130     void GetEnregisteredValue(MemoryRange valueOutBuffer);
8131
8132     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
8133     // instance of a derived class of EnregisteredValueHome
8134     virtual
8135     void CopyToIPCEType(RemoteAddress * pRegAddr);
8136
8137 }; // class MemRegValueHome;
8138
8139 // class FloatRegValueHome
8140 // derived class to add an index into the FP register stack for a floating point value
8141 class FloatRegValueHome: public EnregisteredValueHome
8142 {
8143 public:
8144     // initializing constructor 
8145     // Arguments:
8146     //     input:  pFrame - frame to which the value belongs
8147     //             index  - index into the floating point stack where the value resides
8148     //     output: no out parameters, but the instance has been initialized
8149     FloatRegValueHome(const CordbNativeFrame *      pFrame,
8150                       DWORD                         index):
8151         EnregisteredValueHome(pFrame),
8152         m_floatIndex(index)
8153     {};
8154
8155     // copy constructor
8156     // Arguments:
8157     //     input:  pRemoteRegAddr - instance of a remote register address from which the values for this
8158     //                              instance will come
8159     //     output: no out parameters, but the instance has been initialized
8160     FloatRegValueHome(const FloatRegValueHome * pRemoteRegAddr):
8161         EnregisteredValueHome(pRemoteRegAddr->m_pFrame),
8162         m_floatIndex(pRemoteRegAddr->m_floatIndex)
8163     {};
8164
8165     // make a copy of this instance of FloatRegValueHome
8166     virtual
8167     FloatRegValueHome * Clone() const { return new FloatRegValueHome(*this); };
8168
8169     // set the value of a remote enregistered value
8170     virtual
8171     void SetEnregisteredValue(MemoryRange newValue, DT_CONTEXT * pContext, bool fIsSigned);
8172
8173     // Gets an enregistered value and returns it to the caller
8174     virtual
8175     void GetEnregisteredValue(MemoryRange valueOutBuffer);
8176
8177     // initialize an instance of RemoteAddress for use in an IPC event buffer with values from this
8178     // instance of a derived class of EnregisteredValueHome
8179     virtual
8180     void CopyToIPCEType(RemoteAddress * pRegAddr);
8181
8182     //-------------------------------------
8183     // data members
8184     //------------------------------------- 
8185     
8186 protected:    
8187     // index into the FP registers for the register in which the floating point value resides
8188     const DWORD            m_floatIndex;
8189  }; // class FloatRegValueHome
8190
8191 // ----------------------------------------------------------------------------
8192 // Type hierarchy for value locations
8193 //                                               ValueHome 
8194 //                                                 | | |
8195 //                           ------------------  |  -------------------
8196 //                      |                    |                     |
8197 //              RemoteValueHome      RegisterValueHome       HandleValueHome
8198 //                 |       |                       
8199 //         --------         -------                      
8200 //        |                            |                    
8201 // VCRemoteValueHome      RefRemoteValueHome                  
8202 // 
8203 // ValueHome:           abstract base class, provides remote read and write utilities
8204 // RemoteValueHome:     used for CordbObjectValue, CordbArrayValue, and CordbBoxValue instances,
8205 //                      which have only remote locations, and for other ICDValues with a remote address
8206 // RegisterValueHome:   used for CordbGenericValue and CordbReferenceValue instances with 
8207 //                      only a register location            
8208 // HandleValueHome:     used for CordbReferenceValue instances with only an object handle 
8209 // VCRemoteValueHome:   used for CordbVCObjectValue instances to supply special operation CreateInternalValue for 
8210 //                      value class objects with only a remote location
8211 // RefRemoteValueHome:  used for CordbReferenceValue instances with only a remote location
8212 // 
8213 // In addition, we have a special type for the ValueHome field for CordbReferenceValue instances:
8214 // RefValueHome. This will have a field of type ValueHome and will implement extra operations only relevant
8215 // for object references.
8216 //                                     
8217 // ----------------------------------------------------------------------------
8218 // 
8219 class ValueHome
8220 {
8221 public:
8222     ValueHome(CordbProcess * pProcess):
8223       m_pProcess(pProcess) { _ASSERTE(pProcess != NULL); };
8224  
8225     // releases resources as necessary
8226     virtual
8227     void Clear() = 0;
8228
8229     // gets the remote address for the value or returns NULL if none exists
8230     virtual
8231         CORDB_ADDRESS GetAddress() = 0;
8232
8233     // Gets a value and returns it in dest
8234     // Argument: 
8235     //     input:  none (uses fields of the instance)
8236     //     output: dest - buffer containing the value retrieved as long as the returned HRESULT doesn't
8237     //     indicate an error. 
8238     // Note: Throws errors from read process memory operation or GetThreadContext operation
8239     virtual
8240     void GetValue(MemoryRange dest) = 0;
8241
8242     // Sets a location to the value provided in src
8243     // Arguments:
8244     //     input:  src -   buffer containing the new value to be set--memory for this buffer is owned by the caller
8245     //             pType - type information about the value
8246     //     output: none, but on success, changes m_remoteValue to hold the new value
8247     // Note: Throws errors from SafeWriteBuffer 
8248     virtual 
8249     void SetValue(MemoryRange src, CordbType * pType) = 0;
8250
8251     // creates an ICDValue for a field or array element or for the value type of a boxed object
8252     // Arguments: 
8253     //     input:  pType        - type of the internal value
8254     //             offset       - offset to the internal value
8255     //             localAddress - address of thelogical buffer within the parent class' local cached  
8256     //                            copy that holds the internal element
8257     //             size         - size of the internal value
8258     //    output:  ppValue      - the newly created ICDValue instance 
8259     // Note: Throws for a variety of possible failures: OOM, E_FAIL, errors from 
8260     //               ReadProcessMemory.
8261     virtual
8262     void CreateInternalValue(CordbType *       pType,
8263                              SIZE_T            offset,
8264                              void *            localAddress,
8265                              ULONG32           size,
8266                              ICorDebugValue ** ppValue) = 0;
8267
8268     // Gets the value of a field or element of an existing ICDValue instance and returns it in dest
8269     // Arguments
8270     //     input:  offset - offset within the value to the internal field or element
8271     //     output: dest   - buffer to hold the value--memory for this buffer is owned by the caller
8272     // Note: Throws process memory write errors
8273     virtual
8274     void GetInternalValue(MemoryRange dest, SIZE_T offset) = 0;
8275
8276     // copies register information from this to a RemoteAddress instance for FuncEval
8277     // Arguments:
8278     //     output: pRegAddr - copy of information in m_pRemoteRegAddr, converted to 
8279     //                        an instance of RemoteAddress
8280     virtual                        
8281     void CopyToIPCEType(RemoteAddress * pRegAddr) = 0;
8282
8283 private:
8284     // unimplemented copy constructor to prevent passing by value
8285     ValueHome(ValueHome * pValHome);
8286
8287 protected:
8288     // --------------
8289     // data member
8290     // --------------
8291    CordbProcess * m_pProcess;
8292 }; // class ValueHome
8293
8294 // ============================================================================
8295 // RemoteValueHome class
8296 // ============================================================================
8297 // to be used for CordbObjectValue, CordbArrayValue, and CordbBoxValue, none of which ever have anything but
8298 // a remote address
8299 class RemoteValueHome: public ValueHome
8300 {
8301 public:
8302     // constructor
8303     // Note: It's possible that remoteValue.pAddress may be NULL--FuncEval makes
8304     // empty GenericValues for literals in which case we would have neither a remote address nor a
8305     // register address
8306     RemoteValueHome(CordbProcess * pProcess, TargetBuffer remoteValue);
8307     
8308     // gets the remote address for the value
8309     virtual
8310     CORDB_ADDRESS GetAddress() { return m_remoteValue.pAddress; };
8311
8312     // releases resources as necessary
8313     virtual
8314     void Clear() {};
8315
8316     // Gets a value and returns it in dest
8317     virtual
8318     void GetValue(MemoryRange dest);
8319
8320     // Sets a location to the value provided in src
8321     virtual 
8322     void SetValue(MemoryRange src, CordbType * pType);
8323
8324     // creates an ICDValue for a field or array element or for the value type of a boxed object
8325     virtual
8326     void CreateInternalValue(CordbType *       pType,
8327                                 SIZE_T            offset,
8328                                 void *            localAddress,
8329                                 ULONG32           size,
8330                                 ICorDebugValue ** ppValue);
8331
8332     // Gets the value of a field or element of an existing ICDValue instance and returns it in dest
8333     virtual
8334     void GetInternalValue(MemoryRange dest, SIZE_T offset);
8335
8336     // copies register information from this to a RemoteAddress instance for FuncEval
8337     virtual
8338     void CopyToIPCEType(RemoteAddress * pRegAddr);
8339
8340
8341     // ----------------
8342     // data member
8343     // ----------------
8344     
8345 protected:
8346     TargetBuffer  m_remoteValue;
8347 }; // class RemoteValueHome
8348
8349 // ============================================================================
8350 // RegisterValueHome class 
8351 // ============================================================================
8352 // for values that may either have a remote location or be enregistered--
8353 // to be used for CordbGenericValue, and as base for CordbVCObjectValue and CordbReferenceValue
8354 class RegisterValueHome: public ValueHome
8355 {
8356 public:
8357     // constructor
8358     RegisterValueHome(CordbProcess *                pProcess, 
8359                       EnregisteredValueHomeHolder * ppRemoteRegAddr);
8360
8361     // clean up resources
8362     virtual
8363     void Clear();
8364
8365     // gets the remote address for the value or returns NULL if none exists
8366     virtual
8367     CORDB_ADDRESS GetAddress() { return NULL; };
8368
8369     // Gets a value and returns it in dest
8370     virtual
8371     void GetValue(MemoryRange dest);
8372     
8373     // Sets a location to the value provided in src
8374     virtual
8375     void SetValue(MemoryRange src, CordbType * pType);
8376
8377     // creates an ICDValue for a field or array element or for the value type of a boxed object
8378     virtual
8379     void CreateInternalValue(CordbType *       pType,
8380                              SIZE_T            offset,
8381                              void *            localAddress,
8382                              ULONG32           size,
8383                              ICorDebugValue ** ppValue);
8384
8385     // Gets the value of a field or element of an existing ICDValue instance and returns it in dest
8386     virtual
8387     void GetInternalValue(MemoryRange dest, SIZE_T offset);
8388
8389     // copies the register information from this to a RemoteAddress instance 
8390     virtual
8391     void CopyToIPCEType(RemoteAddress * pRegAddr);
8392
8393 protected:
8394
8395     // sets a remote enregistered location to a new value
8396     void SetEnregisteredValue(MemoryRange src, bool fIsSigned);
8397     
8398     // gets a value from an enregistered location
8399     void GetEnregisteredValue(MemoryRange dest); 
8400
8401     bool IsSigned(CorElementType elementType);
8402
8403     // ----------------
8404     // data member
8405     // ----------------
8406
8407 protected:
8408     // Left Side register location info for various kinds of (partly) enregistered values.
8409     EnregisteredValueHome * m_pRemoteRegAddr; 
8410
8411 }; // class RegisterValueHome
8412
8413 // ============================================================================
8414 // HandleValueHome class
8415 // ============================================================================
8416
8417 class HandleValueHome: public ValueHome
8418 {
8419 public:
8420     // constructor
8421     // Arguments:
8422     //     input:  pProcess   -  process to which the value belongs
8423     //             vmObjHandle - objectHandle holding the object address
8424     HandleValueHome(CordbProcess * pProcess, VMPTR_OBJECTHANDLE vmObjHandle):
8425         ValueHome(pProcess),
8426         m_vmObjectHandle(vmObjHandle) {};
8427
8428     // releases resources as necessary   
8429     virtual
8430     void Clear() {};
8431
8432     // gets the remote address for the value or returns NULL if none exists
8433     virtual
8434     CORDB_ADDRESS GetAddress();
8435
8436     // Gets a value and returns it in dest
8437     virtual
8438     void GetValue(MemoryRange dest);
8439     
8440     // Sets a location to the value provided in src
8441     virtual
8442     void SetValue(MemoryRange src, CordbType * pType);
8443
8444     // creates an ICDValue for a field or array element or for the value type of a boxed object
8445     virtual
8446     void CreateInternalValue(CordbType *       pType,
8447                              SIZE_T            offset,
8448                              void *            localAddress,
8449                              ULONG32           size,
8450                              ICorDebugValue ** ppValue);
8451
8452     // Gets the value of a field or element of an existing ICDValue instance and returns it in dest
8453     virtual
8454     void GetInternalValue(MemoryRange dest, SIZE_T offset);
8455
8456     // copies the register information from this to a RemoteAddress instance 
8457     virtual
8458     void CopyToIPCEType(RemoteAddress * pRegAddr);
8459
8460     // ----------------
8461     // data member
8462     // ----------------
8463 private:
8464     VMPTR_OBJECTHANDLE m_vmObjectHandle;
8465 }; // class HandleValueHome;
8466
8467 // ============================================================================
8468 // VCRemoteValueHome class
8469 // ============================================================================
8470 // used only for CordbVCObjectValue
8471 class VCRemoteValueHome: public RemoteValueHome
8472 {
8473 public:
8474     // constructor
8475     VCRemoteValueHome(CordbProcess * pProcess, 
8476                       TargetBuffer   remoteValue):
8477         RemoteValueHome(pProcess, remoteValue) {};
8478
8479     // Sets a location to the value provided in src 
8480     virtual
8481     void SetValue(MemoryRange src, CordbType * pType);
8482
8483 }; // class VCRemoteValueHome
8484
8485 // ============================================================================
8486 // RefRemoteValueHome class
8487 // ============================================================================
8488
8489 // used only for CordbReferenceValue
8490 class RefRemoteValueHome: public RemoteValueHome
8491 {
8492 public:
8493     // constructor
8494     // Arguments
8495     RefRemoteValueHome(CordbProcess *                pProcess, 
8496                        TargetBuffer                  remoteValue);
8497
8498     // Sets a location to the value provided in src
8499     virtual
8500     void SetValue(MemoryRange src, CordbType * pType);
8501
8502 }; // class RefRemoteValueHome
8503
8504 // ============================================================================
8505 // RefValueHome class
8506 // ============================================================================
8507
8508 // abstract superclass for derivations RefRemoteValueHome and RefRegValueHome
8509 class RefValueHome
8510 {
8511 public:
8512     // constructor
8513     RefValueHome() { m_pHome = NULL; m_fNullObjHandle = true; };
8514
8515     // constructor
8516     RefValueHome(CordbProcess *                pProcess, 
8517                  TargetBuffer                  remoteValue,
8518                  EnregisteredValueHomeHolder * ppRemoteRegAddr,
8519                  VMPTR_OBJECTHANDLE            vmObjHandle);
8520
8521     // indicates whether the object handle is null
8522     bool ObjHandleIsNull() { return m_fNullObjHandle; };
8523     void SetObjHandleFlag(bool isNull) { m_fNullObjHandle = isNull; };
8524
8525     // ----------------
8526     // data members 
8527     // ----------------
8528     // appropriate instantiation of ValueHome 
8529     ValueHome * m_pHome;
8530
8531 private:
8532     // true iff m_pHome is an instantiation of RemoteValueHome or RegisterValueHome  
8533     bool m_fNullObjHandle;
8534 }; // class RefValueHome
8535
8536 typedef enum {kUnboxed, kBoxed} BoxedValue;
8537 #define EMPTY_BUFFER TargetBuffer(PTR_TO_CORDB_ADDRESS((void *)NULL), 0)
8538
8539 // for an inheritance graph of the ICDValue types, // See file:./ICorDebugValueTypes.vsd for a diagram of the types.  
8540 /* ------------------------------------------------------------------------- *
8541  * Value class
8542  * ------------------------------------------------------------------------- */
8543
8544 class CordbValue : public CordbBase
8545 {
8546 public:
8547     //-----------------------------------------------------------
8548     // Constructor/destructor
8549     //-----------------------------------------------------------
8550     CordbValue(CordbAppDomain * appdomain,
8551                CordbType *      type,
8552                CORDB_ADDRESS    id,
8553                bool             isLiteral,
8554                NeuterList *     pList = NULL);
8555
8556     virtual ~CordbValue();
8557     virtual void Neuter();
8558
8559     //-----------------------------------------------------------
8560     // IUnknown
8561     //-----------------------------------------------------------
8562
8563     ULONG STDMETHODCALLTYPE AddRef()
8564     {
8565         return (BaseAddRef());
8566     }
8567     ULONG STDMETHODCALLTYPE Release()
8568     {
8569         return (BaseRelease());
8570     }
8571
8572     //-----------------------------------------------------------
8573     // ICorDebugValue
8574     //-----------------------------------------------------------
8575
8576     COM_METHOD GetType(CorElementType *pType)
8577     {
8578         LIMITED_METHOD_CONTRACT;
8579
8580         FAIL_IF_NEUTERED(this);
8581         VALIDATE_POINTER_TO_OBJECT(pType, CorElementType *);
8582
8583         *pType = m_type->m_elementType;
8584         return (S_OK);
8585     }
8586
8587     COM_METHOD GetSize(ULONG32 *pSize)
8588     {
8589         LIMITED_METHOD_CONTRACT;
8590
8591         FAIL_IF_NEUTERED(this);
8592         VALIDATE_POINTER_TO_OBJECT(pSize, ULONG32 *);
8593
8594         if (m_size > ULONG_MAX)
8595         {
8596             *pSize = ULONG_MAX;
8597             return (COR_E_OVERFLOW);
8598         }
8599
8600         *pSize = (ULONG)m_size;
8601         return (S_OK);
8602     }
8603
8604     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint);
8605
8606     //-----------------------------------------------------------
8607     // ICorDebugValue2
8608     //-----------------------------------------------------------
8609
8610     COM_METHOD GetExactType(ICorDebugType **ppType);
8611
8612     //-----------------------------------------------------------
8613     // ICorDebugValue3
8614     //-----------------------------------------------------------
8615
8616     COM_METHOD GetSize64(ULONG64 *pSize)
8617     {
8618         LIMITED_METHOD_CONTRACT;
8619
8620         FAIL_IF_NEUTERED(this);
8621         VALIDATE_POINTER_TO_OBJECT(pSize, ULONG64 *);
8622
8623         *pSize = m_size;
8624         return (S_OK);
8625     }
8626
8627     //-----------------------------------------------------------
8628     // Methods not exported through COM
8629     //-----------------------------------------------------------
8630
8631     // Helper for code:CordbValue::CreateValueByType. Create a new instance of CordbGenericValue
8632     static 
8633     void CreateGenericValue(CordbAppDomain *               pAppdomain,
8634                             CordbType *                    pType,
8635                             TargetBuffer                   remoteValue,
8636                             MemoryRange                    localValue,
8637                             EnregisteredValueHomeHolder *  ppRemoteRegAddr,
8638                             ICorDebugValue**               ppValue);
8639
8640     // Helper for code:CordbValue::CreateValueByType. Create a new instance of CordbVCObjectValue or 
8641     // CordbReferenceValue
8642     static                  
8643     void CreateVCObjOrRefValue(CordbAppDomain *               pAppdomain,
8644                                CordbType *                    pType,
8645                                bool                           boxed,
8646                                TargetBuffer                   remoteValue,
8647                                MemoryRange                    localValue,
8648                                EnregisteredValueHomeHolder *  ppRemoteRegAddr,
8649                                ICorDebugValue**               ppValue);
8650
8651     // Create the proper ICDValue instance based on the given element type.
8652     static void CreateValueByType(CordbAppDomain *               appdomain,
8653                                   CordbType *                    type,
8654                                   bool                           boxed,
8655                                   TargetBuffer                   remoteValue,
8656                                   MemoryRange                    localValue,
8657                                   EnregisteredValueHomeHolder *  ppRemoteRegAddr,
8658                                   ICorDebugValue**               ppValue);
8659
8660     // Create the proper ICDValue instance based on the given remote heap object
8661     static ICorDebugValue* CreateHeapValue(CordbAppDomain* pAppDomain,
8662                                            VMPTR_Object vmObj);
8663
8664
8665     // Returns a pointer to the ValueHome field of this instance of CordbValue if one exists or NULL
8666     // otherwise. Therefore, this also tells us indirectly whether this instance of CordbValue is also an
8667     // instance of one of its derived types and thus has a ValueHome field.
8668     virtual
8669     ValueHome * GetValueHome() { return NULL; };
8670
8671     static ULONG32 GetSizeForType(CordbType * pType, BoxedValue boxing);
8672
8673     virtual CordbAppDomain *GetAppDomain()
8674     {
8675         return m_appdomain;
8676     }
8677
8678     HRESULT InternalCreateHandle(
8679         CorDebugHandleType handleType,
8680         ICorDebugHandleValue ** ppHandle);
8681
8682     //-----------------------------------------------------------
8683     // Data members
8684     //-----------------------------------------------------------
8685
8686 public:
8687     CordbAppDomain *            m_appdomain;
8688     RSSmartPtr<CordbType>       m_type;
8689
8690     // size of the value  
8691     SIZE_T                      m_size;
8692
8693     // true if the value is a RS fabrication.
8694     bool                        m_isLiteral;     
8695
8696 };
8697
8698 /* ------------------------------------------------------------------------- *
8699  * Value Breakpoint class
8700  * ------------------------------------------------------------------------- */
8701
8702 class CordbValueBreakpoint : public CordbBreakpoint,
8703                              public ICorDebugValueBreakpoint
8704 {
8705 public:
8706     CordbValueBreakpoint(CordbValue *pValue);
8707
8708
8709 #ifdef _DEBUG
8710     virtual const char * DbgGetName() { return "CordbValueBreakpoint"; }
8711 #endif
8712
8713     //-----------------------------------------------------------
8714     // IUnknown
8715     //-----------------------------------------------------------
8716
8717     ULONG STDMETHODCALLTYPE AddRef()
8718     {
8719         return (BaseAddRef());
8720     }
8721     ULONG STDMETHODCALLTYPE Release()
8722     {
8723         return (BaseRelease());
8724     }
8725     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
8726
8727     //-----------------------------------------------------------
8728     // ICorDebugValueBreakpoint
8729     //-----------------------------------------------------------
8730
8731     COM_METHOD GetValue(ICorDebugValue **ppValue);
8732     COM_METHOD Activate(BOOL bActive);
8733     COM_METHOD IsActive(BOOL *pbActive)
8734     {
8735         VALIDATE_POINTER_TO_OBJECT(pbActive, BOOL *);
8736
8737         return BaseIsActive(pbActive);
8738     }
8739
8740     //-----------------------------------------------------------
8741     // Non-COM methods
8742     //-----------------------------------------------------------
8743
8744     void Disconnect();
8745
8746 public:
8747     CordbValue       *m_value;
8748 };
8749
8750 /* ------------------------------------------------------------------------- *
8751  * Generic Value class
8752  * ------------------------------------------------------------------------- */
8753
8754 class CordbGenericValue : public CordbValue, public ICorDebugGenericValue, public ICorDebugValue2, public ICorDebugValue3
8755 {
8756 public:
8757     CordbGenericValue(CordbAppDomain *              appdomain,
8758                       CordbType *                   type,
8759                       TargetBuffer                  remoteValue,
8760                       EnregisteredValueHomeHolder * ppRemoteRegAddr);
8761
8762     CordbGenericValue(CordbType * pType);
8763     // destructor
8764     ~CordbGenericValue();
8765
8766 #ifdef _DEBUG
8767     virtual const char * DbgGetName() { return "CordbGenericValue"; }
8768 #endif
8769
8770
8771     //-----------------------------------------------------------
8772     // IUnknown
8773     //-----------------------------------------------------------
8774
8775     ULONG STDMETHODCALLTYPE AddRef()
8776     {
8777         return (BaseAddRef());
8778     }
8779     ULONG STDMETHODCALLTYPE Release()
8780     {
8781         return (BaseRelease());
8782     }
8783     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
8784
8785     //-----------------------------------------------------------
8786     // ICorDebugValue
8787     //-----------------------------------------------------------
8788
8789     // gets the type of the value
8790     // Arguments: 
8791     //     output: pType - the type of the value. The caller must guarantee that pType is non-null.
8792     // Return Value: S_OK on success, E_INVALIDARG on failure
8793     COM_METHOD GetType(CorElementType *pType)
8794     {
8795         return (CordbValue::GetType(pType));
8796     }
8797
8798     // gets the size of the value
8799     // Arguments: 
8800     //     output: pSize - the size of the value. The caller must guarantee that pSize is non-null.
8801     // Return Value: S_OK on success, E_INVALIDARG on failure
8802     COM_METHOD GetSize(ULONG32 *pSize)
8803     {
8804         return (CordbValue::GetSize(pSize));
8805     }
8806     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
8807     {
8808         return (CordbValue::CreateBreakpoint(ppBreakpoint));
8809     }
8810
8811     // gets the remote (LS) address of the value. This may return NULL if the 
8812     // value is a literal or resides in a register. 
8813     // Arguments:
8814     //     output: pAddress - the address of the value. The caller must guarantee is
8815     //             non-Null
8816     // Return Value: S_OK on success or E_INVALIDARG if pAddress is null
8817     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress)
8818     {
8819         LIMITED_METHOD_CONTRACT;
8820
8821         FAIL_IF_NEUTERED(this);
8822         VALIDATE_POINTER_TO_OBJECT_OR_NULL(pAddress, CORDB_ADDRESS *);
8823
8824         *pAddress = m_pValueHome ? m_pValueHome->GetAddress() : NULL;
8825         return (S_OK);
8826     }
8827
8828     //-----------------------------------------------------------
8829     // ICorDebugValue2
8830     //-----------------------------------------------------------
8831
8832     COM_METHOD GetExactType(ICorDebugType **ppType)
8833     {
8834         return (CordbValue::GetExactType(ppType));
8835     }
8836
8837     //-----------------------------------------------------------
8838     // ICorDebugValue3
8839     //-----------------------------------------------------------
8840
8841     COM_METHOD GetSize64(ULONG64 *pSize)
8842     {
8843         return (CordbValue::GetSize64(pSize));
8844     }
8845
8846     //-----------------------------------------------------------
8847     // ICorDebugGenericValue
8848     //-----------------------------------------------------------
8849
8850     COM_METHOD GetValue(void *pTo);
8851     COM_METHOD SetValue(void *pFrom);
8852
8853     //-----------------------------------------------------------
8854     // Non-COM methods
8855     //-----------------------------------------------------------
8856
8857     // initialize a generic value by copying the necessary data, either
8858     // from the remote process or from another value in this process.
8859     void Init(MemoryRange localValue);
8860     bool CopyLiteralData(BYTE *pBuffer);
8861
8862     // Returns a pointer to the ValueHome field
8863     virtual
8864     ValueHome * GetValueHome() { return m_pValueHome; };
8865
8866     //-----------------------------------------------------------
8867     // Data members
8868     //-----------------------------------------------------------
8869
8870 private:
8871     // hold copies of up to 64-bit values.
8872     BYTE  m_pCopyOfData[8]; 
8873
8874     // location information--remote or register address
8875     ValueHome * m_pValueHome;
8876 };
8877
8878
8879 /* ------------------------------------------------------------------------- *
8880  * Reference Value class
8881  * ------------------------------------------------------------------------- */
8882
8883 class CordbReferenceValue : public CordbValue, public ICorDebugReferenceValue, public ICorDebugValue2, public ICorDebugValue3
8884 {
8885 public:
8886     CordbReferenceValue(CordbAppDomain *              pAppdomain,
8887                         CordbType *                   pType,
8888                         MemoryRange                   localValue,
8889                         TargetBuffer                  remoteValue,
8890                         EnregisteredValueHomeHolder * ppRegAddr,
8891                         VMPTR_OBJECTHANDLE            vmObjectHandle);
8892     CordbReferenceValue(CordbType * pType);
8893     virtual ~CordbReferenceValue();
8894     virtual void Neuter();
8895
8896
8897 #ifdef _DEBUG
8898     virtual const char * DbgGetName() { return "CordbReferenceValue"; }
8899 #endif
8900
8901     //-----------------------------------------------------------
8902     // IUnknown
8903     //-----------------------------------------------------------
8904
8905     ULONG STDMETHODCALLTYPE AddRef()
8906     {
8907         return (BaseAddRef());
8908     }
8909     ULONG STDMETHODCALLTYPE Release()
8910     {
8911         return (BaseRelease());
8912     }
8913     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
8914
8915     //-----------------------------------------------------------
8916     // ICorDebugValue
8917     //-----------------------------------------------------------
8918
8919     COM_METHOD GetType(CorElementType *pType);
8920
8921     // get the size of the reference
8922     // Arguments: 
8923     //     output: pSize - the size of the value--this must be non-NULL
8924     // Return Value: S_OK on success or E_INVALIDARG
8925     COM_METHOD GetSize(ULONG32 *pSize)
8926     {
8927         return (CordbValue::GetSize(pSize));
8928     }
8929
8930     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress);
8931     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
8932     {
8933         return (CordbValue::CreateBreakpoint(ppBreakpoint));
8934     }
8935
8936     //-----------------------------------------------------------
8937     // ICorDebugValue2
8938     //-----------------------------------------------------------
8939
8940     COM_METHOD GetExactType(ICorDebugType **ppType)
8941     {
8942         return (CordbValue::GetExactType(ppType));
8943     }
8944
8945     //-----------------------------------------------------------
8946     // ICorDebugValue3
8947     //-----------------------------------------------------------
8948
8949     COM_METHOD GetSize64(ULONG64 *pSize)
8950     {
8951         return (CordbValue::GetSize64(pSize));
8952     }
8953
8954     //-----------------------------------------------------------
8955     // ICorDebugReferenceValue
8956     //-----------------------------------------------------------
8957
8958     COM_METHOD IsNull(BOOL * pfIsNull);
8959     COM_METHOD GetValue(CORDB_ADDRESS *pAddress);
8960     COM_METHOD SetValue(CORDB_ADDRESS address);
8961     COM_METHOD Dereference(ICorDebugValue **ppValue);
8962     COM_METHOD DereferenceStrong(ICorDebugValue **ppValue);
8963
8964     //-----------------------------------------------------------
8965     // Non-COM methods
8966     //-----------------------------------------------------------
8967
8968     // Helper function for SanityCheckPointer. Make an attempt to read memory at the address which is the
8969     // value of the reference.
8970     void TryDereferencingTarget();
8971
8972     // Do a sanity check on the pointer which is the value of the object reference. We can't efficiently
8973     // ensure that the pointer is really good, so we settle for a quick check just to make sure the memory at
8974     // the address is readable. We're actually just checking that we can dereference the pointer.
8975     // If the address is invalid, this will throw.
8976     void SanityCheckPointer (CorElementType type);
8977
8978     // get information about the reference when it's not an object address but another kind of pointer type:
8979     // ELEMENT_TYPE_BYREF, ELEMENT_TYPE_PTR or ELEMENT_TYPE_FNPTR
8980     void GetPointerData(CorElementType type, MemoryRange localValue);
8981
8982     // get basic object specific data when a reference points to an object, plus extra data if the object is
8983     // an array or string
8984     static
8985     void GetObjectData(CordbProcess *            pProcess, 
8986                        void *                    objectAddress, 
8987                        CorElementType            type, 
8988                        VMPTR_AppDomain           vmAppdomain,
8989                        DebuggerIPCE_ObjectData * pInfo);
8990
8991     // get information about a TypedByRef object when the reference is the address of a TypedByRef structure.
8992     static
8993     void GetTypedByRefData(CordbProcess *            pProcess, 
8994                            CORDB_ADDRESS             pTypedByRef, 
8995                            CorElementType            type, 
8996                            VMPTR_AppDomain           vmAppDomain,
8997                            DebuggerIPCE_ObjectData * pInfo);
8998
8999     //  get the address of the object referenced
9000     void * GetObjectAddress(MemoryRange localValue);
9001
9002     // update type information after initializing -- when we initialize, we may get more exact type
9003     // information than we previously had
9004     void UpdateTypeInfo();
9005
9006     // Initialize this CordbReferenceValue. This may involve inspecting the LS to get information about the
9007     // referent.
9008     HRESULT InitRef(MemoryRange localValue);
9009
9010     bool CopyLiteralData(BYTE *pBuffer);
9011
9012     static HRESULT Build(CordbAppDomain *              appdomain,
9013                          CordbType *                   type,
9014                          TargetBuffer                  remoteValue,
9015                          MemoryRange                   localValue,
9016                          VMPTR_OBJECTHANDLE            vmObjectHandle,
9017                          EnregisteredValueHomeHolder * ppRemoteRegAddr,
9018                          CordbReferenceValue**         ppValue);
9019
9020     static HRESULT BuildFromGCHandle(CordbAppDomain *pAppDomain, VMPTR_OBJECTHANDLE gcHandle, ICorDebugReferenceValue ** pOutRef);
9021
9022     // Common dereference routine shared by both CordbReferenceValue + CordbHandleValue
9023     static HRESULT DereferenceCommon(CordbAppDomain *          pAppDomain,
9024                                      CordbType *               pType,
9025                                      CordbType *               pRealTypeOfTypedByref,
9026                                      DebuggerIPCE_ObjectData * m_pInfo,
9027                                      ICorDebugValue **         ppValue);
9028
9029     // Returns a pointer to the ValueHome field
9030     virtual
9031     ValueHome * GetValueHome() { return m_valueHome.m_pHome; };
9032
9033     //-----------------------------------------------------------
9034     // Data members
9035     //-----------------------------------------------------------
9036
9037 public:
9038     DebuggerIPCE_ObjectData  m_info;
9039     CordbType *              m_realTypeOfTypedByref; // weak ref
9040
9041     RefValueHome             m_valueHome;
9042
9043     // Indicates when we last syncronized our stored data (m_info) from the left side
9044     UINT                     m_continueCounterLastSync;
9045 };
9046
9047 /* ------------------------------------------------------------------------- *
9048  * Object Value class
9049  *
9050  * Because of the oddness of string objects in the Runtime we have one
9051  * object that implements both ObjectValue and StringValue. There is a
9052  * definite string type, but its really just an object of the string
9053  * class. Furthermore, you can have a variable whose type is listed as
9054  * "class", but its an instance of the string class and therefore needs
9055  * to be treated like a string. 
9056  * ------------------------------------------------------------------------- */
9057
9058 class CordbObjectValue : public CordbValue, 
9059                          public ICorDebugObjectValue,
9060                          public ICorDebugObjectValue2,
9061                          public ICorDebugGenericValue,
9062                          public ICorDebugStringValue, 
9063                          public ICorDebugValue2,
9064                          public ICorDebugValue3,
9065                          public ICorDebugHeapValue2,
9066                          public ICorDebugHeapValue3,
9067                          public ICorDebugExceptionObjectValue,
9068                          public ICorDebugComObjectValue
9069 {
9070 public:
9071     
9072     CordbObjectValue(CordbAppDomain *          appdomain,
9073                      CordbType *               type,
9074                      TargetBuffer              remoteValue,
9075                      DebuggerIPCE_ObjectData * pObjectData );
9076                      
9077     virtual ~CordbObjectValue();
9078
9079
9080     virtual void Neuter();
9081 #ifdef _DEBUG
9082     virtual const char * DbgGetName() { return "CordbObjectValue"; }
9083 #endif
9084
9085     //-----------------------------------------------------------
9086     // IUnknown
9087     //-----------------------------------------------------------
9088
9089     ULONG STDMETHODCALLTYPE AddRef()
9090     {
9091         return (BaseAddRef());
9092     }
9093     ULONG STDMETHODCALLTYPE Release()
9094     {
9095         return (BaseRelease());
9096     }
9097     COM_METHOD QueryInterface(REFIID riid, void ** ppInterface);
9098
9099     //-----------------------------------------------------------
9100     // ICorDebugValue
9101     //-----------------------------------------------------------
9102
9103     COM_METHOD GetType(CorElementType * pType);
9104     COM_METHOD GetSize(ULONG32 * pSize);
9105     COM_METHOD GetAddress(CORDB_ADDRESS * pAddress);
9106     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint ** ppBreakpoint);
9107
9108     //-----------------------------------------------------------
9109     // ICorDebugValue2
9110     //-----------------------------------------------------------
9111
9112     COM_METHOD GetExactType(ICorDebugType ** ppType)
9113     {
9114         return (CordbValue::GetExactType(ppType));
9115     }
9116
9117     //-----------------------------------------------------------
9118     // ICorDebugValue3
9119     //-----------------------------------------------------------
9120
9121     COM_METHOD GetSize64(ULONG64 *pSize);
9122
9123     //-----------------------------------------------------------
9124     // ICorDebugHeapValue
9125     //-----------------------------------------------------------
9126
9127     COM_METHOD IsValid(BOOL * pfIsValid);
9128     COM_METHOD CreateRelocBreakpoint(ICorDebugValueBreakpoint ** ppBreakpoint);
9129
9130     //-----------------------------------------------------------
9131     // ICorDebugHeapValue2
9132     //-----------------------------------------------------------
9133     COM_METHOD CreateHandle(CorDebugHandleType type, ICorDebugHandleValue ** ppHandle);
9134
9135     //-----------------------------------------------------------
9136     // ICorDebugHeapValue3
9137     //-----------------------------------------------------------
9138     COM_METHOD GetThreadOwningMonitorLock(ICorDebugThread **ppThread, DWORD *pAcquisitionCount);
9139     COM_METHOD GetMonitorEventWaitList(ICorDebugThreadEnum **ppThreadEnum);
9140
9141     //-----------------------------------------------------------
9142     // ICorDebugObjectValue
9143     //-----------------------------------------------------------
9144
9145     COM_METHOD GetClass(ICorDebugClass ** ppClass);
9146     COM_METHOD GetFieldValue(ICorDebugClass *  pClass,
9147                              mdFieldDef        fieldDef,
9148                              ICorDebugValue ** ppValue);
9149     COM_METHOD GetVirtualMethod(mdMemberRef memberRef,
9150                                 ICorDebugFunction **ppFunction);
9151     COM_METHOD GetContext(ICorDebugContext ** ppContext);
9152     COM_METHOD IsValueClass(BOOL * pfIsValueClass);
9153     COM_METHOD GetManagedCopy(IUnknown ** ppObject);
9154     COM_METHOD SetFromManagedCopy(IUnknown * pObject);
9155
9156     COM_METHOD GetFieldValueForType(ICorDebugType *   pType,
9157                                     mdFieldDef        fieldDef,
9158                                     ICorDebugValue ** ppValue);
9159
9160     COM_METHOD GetVirtualMethodAndType(mdMemberRef          memberRef,
9161                                        ICorDebugFunction ** ppFunction,
9162                                        ICorDebugType **     ppType);
9163
9164     //-----------------------------------------------------------
9165     // ICorDebugGenericValue
9166     //-----------------------------------------------------------
9167
9168     COM_METHOD GetValue(void * pTo);
9169     COM_METHOD SetValue(void * pFrom);
9170
9171     //-----------------------------------------------------------
9172     // ICorDebugStringValue
9173     //-----------------------------------------------------------
9174     COM_METHOD GetLength(ULONG32 * pcchString);
9175     COM_METHOD GetString(ULONG32   cchString,
9176                          ULONG32 * ppcchStrin,
9177                          __out_ecount_opt(cchString) WCHAR     szString[]);
9178
9179     //-----------------------------------------------------------
9180     // ICorDebugExceptionObjectValue
9181     //-----------------------------------------------------------
9182     COM_METHOD EnumerateExceptionCallStack(ICorDebugExceptionObjectCallStackEnum** ppCallStackEnum);
9183
9184     //-----------------------------------------------------------
9185     // ICorDebugComObjectValue
9186     //-----------------------------------------------------------
9187     COM_METHOD GetCachedInterfaceTypes(BOOL bIInspectableOnly, 
9188                         ICorDebugTypeEnum** ppInterfacesEnum);
9189
9190     COM_METHOD GetCachedInterfacePointers(BOOL bIInspectableOnly, 
9191                         ULONG32 celt,
9192                         ULONG32 *pcEltFetched,
9193                         CORDB_ADDRESS * ptrs);
9194
9195     //-----------------------------------------------------------
9196     // Non-COM methods
9197     //-----------------------------------------------------------
9198
9199     HRESULT Init();
9200
9201     DebuggerIPCE_ObjectData GetInfo() { return m_info; }
9202     CordbHangingFieldTable * GetHangingFieldTable() { return &m_hangingFieldsInstance; }
9203
9204     // Returns a pointer to the ValueHome field
9205     virtual
9206     RemoteValueHome * GetValueHome() { return &m_valueHome; };
9207
9208 protected:
9209     //-----------------------------------------------------------
9210     // Data members
9211     //-----------------------------------------------------------
9212     DebuggerIPCE_ObjectData  m_info;
9213     BYTE *                   m_pObjectCopy;     // local cached copy of the object
9214     BYTE *                   m_objectLocalVars; // var base in _this_ process
9215                                                 // points _into_ m_pObjectCopy
9216     BYTE *                   m_stringBuffer;    // points _into_ m_pObjectCopy
9217
9218     // remote location information
9219     RemoteValueHome          m_valueHome;
9220
9221     // If instances fields are added by EnC, their storage will be off the objects
9222     // syncblock.  Cache per-object information about such fields here.
9223     CordbHangingFieldTable   m_hangingFieldsInstance;
9224
9225 private:
9226     HRESULT IsExceptionObject();
9227
9228     BOOL                     m_fIsExceptionObject;
9229
9230     HRESULT IsRcw();
9231
9232     BOOL                     m_fIsRcw;
9233 };
9234
9235 /* ------------------------------------------------------------------------- *
9236  * Value Class Object Value class
9237  * ------------------------------------------------------------------------- */
9238
9239 class CordbVCObjectValue : public CordbValue,
9240                            public ICorDebugObjectValue, public ICorDebugObjectValue2,
9241                            public ICorDebugGenericValue, public ICorDebugValue2,
9242                            public ICorDebugValue3
9243 {
9244 public:
9245     CordbVCObjectValue(CordbAppDomain *               pAppdomain,
9246                        CordbType *                    pType,
9247                        TargetBuffer                   remoteValue,
9248                        EnregisteredValueHomeHolder *  ppRemoteRegAddr);
9249     virtual ~CordbVCObjectValue();
9250
9251 #ifdef _DEBUG
9252     virtual const char * DbgGetName() { return "CordbVCObjectValue"; }
9253 #endif
9254
9255     //-----------------------------------------------------------
9256     // IUnknown
9257     //-----------------------------------------------------------
9258
9259     ULONG STDMETHODCALLTYPE AddRef()
9260     {
9261         return (BaseAddRef());
9262     }
9263     ULONG STDMETHODCALLTYPE Release()
9264     {
9265         return (BaseRelease());
9266     }
9267     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9268
9269     //-----------------------------------------------------------
9270     // ICorDebugValue
9271     //-----------------------------------------------------------
9272
9273     COM_METHOD GetType(CorElementType *pType);
9274
9275     COM_METHOD GetSize(ULONG32 *pSize)
9276     {
9277         return (CordbValue::GetSize(pSize));
9278     }
9279     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
9280     {
9281         return (CordbValue::CreateBreakpoint(ppBreakpoint));
9282     }
9283
9284     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress)
9285     {
9286         LIMITED_METHOD_CONTRACT;
9287
9288         FAIL_IF_NEUTERED(this);
9289         VALIDATE_POINTER_TO_OBJECT(pAddress, CORDB_ADDRESS *);
9290
9291         *pAddress = m_pValueHome->GetAddress();
9292         return (S_OK);
9293     }
9294
9295     //-----------------------------------------------------------
9296     // ICorDebugValue2
9297     //-----------------------------------------------------------
9298
9299     COM_METHOD GetExactType(ICorDebugType **ppType)
9300     {
9301         return (CordbValue::GetExactType(ppType));
9302     }
9303
9304     //-----------------------------------------------------------
9305     // ICorDebugValue3
9306     //-----------------------------------------------------------
9307
9308     COM_METHOD GetSize64(ULONG64 *pSize)
9309     {
9310         return (CordbValue::GetSize64(pSize));
9311     }
9312
9313     //-----------------------------------------------------------
9314     // ICorDebugObjectValue
9315     //-----------------------------------------------------------
9316
9317     COM_METHOD GetClass(ICorDebugClass **ppClass);
9318     COM_METHOD GetFieldValue(ICorDebugClass *pClass,
9319                              mdFieldDef fieldDef,
9320                              ICorDebugValue **ppValue);
9321     COM_METHOD GetVirtualMethod(mdMemberRef memberRef,
9322                                 ICorDebugFunction **ppFunction);
9323     COM_METHOD GetContext(ICorDebugContext **ppContext);
9324     COM_METHOD IsValueClass(BOOL *pbIsValueClass);
9325     COM_METHOD GetManagedCopy(IUnknown **ppObject);
9326     COM_METHOD SetFromManagedCopy(IUnknown *pObject);
9327     COM_METHOD GetFieldValueForType(ICorDebugType * pType,
9328                                     mdFieldDef fieldDef,
9329                                     ICorDebugValue ** ppValue);
9330     COM_METHOD GetVirtualMethodAndType(mdMemberRef memberRef,
9331                                        ICorDebugFunction **ppFunction,
9332                                        ICorDebugType **ppType);
9333
9334     //-----------------------------------------------------------
9335     // ICorDebugGenericValue
9336     //-----------------------------------------------------------
9337
9338     COM_METHOD GetValue(void *pTo);
9339     COM_METHOD SetValue(void *pFrom);
9340
9341     //-----------------------------------------------------------
9342     // Non-COM methods
9343     //-----------------------------------------------------------
9344
9345     // Initializes the Right-Side's representation of a Value Class object.
9346     HRESULT Init(MemoryRange localValue);
9347     //HRESULT ResolveValueClass();
9348     CordbClass *GetClass();
9349
9350     // Returns a pointer to the ValueHome field
9351     virtual
9352     ValueHome * GetValueHome() { return m_pValueHome; };
9353
9354     //-----------------------------------------------------------
9355     // Data members
9356     //-----------------------------------------------------------
9357
9358 private:
9359
9360     // local cached copy of the value class
9361     BYTE *   m_pObjectCopy;
9362
9363     // location information
9364     ValueHome * m_pValueHome;
9365 };
9366
9367
9368 /* ------------------------------------------------------------------------- *
9369  * Box Value class
9370  * ------------------------------------------------------------------------- */
9371
9372 class CordbBoxValue : public CordbValue, 
9373                       public ICorDebugBoxValue,
9374                       public ICorDebugGenericValue,
9375                       public ICorDebugValue2,
9376                       public ICorDebugValue3,
9377                       public ICorDebugHeapValue2,
9378                       public ICorDebugHeapValue3
9379 {
9380 public:
9381     CordbBoxValue(CordbAppDomain *  appdomain,
9382                   CordbType *       type,
9383                   TargetBuffer      remoteValue,
9384                   ULONG32           size,
9385                   SIZE_T            offsetToVars);
9386     virtual ~CordbBoxValue();
9387
9388 #ifdef _DEBUG
9389     virtual const char * DbgGetName() { return "CordbBoxValue"; }
9390 #endif
9391
9392     //-----------------------------------------------------------
9393     // IUnknown
9394     //-----------------------------------------------------------
9395
9396     ULONG STDMETHODCALLTYPE AddRef()
9397     {
9398         return (BaseAddRef());
9399     }
9400     ULONG STDMETHODCALLTYPE Release()
9401     {
9402         return (BaseRelease());
9403     }
9404     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9405
9406     //-----------------------------------------------------------
9407     // ICorDebugValue
9408     //-----------------------------------------------------------
9409
9410     COM_METHOD GetType(CorElementType *pType);
9411
9412     COM_METHOD GetSize(ULONG32 *pSize)
9413     {
9414         return (CordbValue::GetSize(pSize));
9415     }
9416     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
9417     {
9418         return (CordbValue::CreateBreakpoint(ppBreakpoint));
9419     }
9420
9421      COM_METHOD GetAddress(CORDB_ADDRESS *pAddress)
9422     {
9423         LIMITED_METHOD_CONTRACT;
9424
9425         FAIL_IF_NEUTERED(this);
9426         VALIDATE_POINTER_TO_OBJECT(pAddress, CORDB_ADDRESS *);
9427
9428         *pAddress = m_valueHome.GetAddress();
9429         return (S_OK);
9430     }
9431
9432     //-----------------------------------------------------------
9433     // ICorDebugValue2
9434     //-----------------------------------------------------------
9435
9436     COM_METHOD GetExactType(ICorDebugType **ppType)
9437     {
9438         return (CordbValue::GetExactType(ppType));
9439     }
9440
9441     //-----------------------------------------------------------
9442     // ICorDebugValue3
9443     //-----------------------------------------------------------
9444
9445     COM_METHOD GetSize64(ULONG64 *pSize)
9446     {
9447         return (CordbValue::GetSize64(pSize));
9448     }
9449
9450     //-----------------------------------------------------------
9451     // ICorDebugHeapValue
9452     //-----------------------------------------------------------
9453
9454     COM_METHOD IsValid(BOOL *pbValid);
9455     COM_METHOD CreateRelocBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint);
9456
9457     //-----------------------------------------------------------
9458     // ICorDebugHeapValue2
9459     //-----------------------------------------------------------
9460     COM_METHOD CreateHandle(CorDebugHandleType type, ICorDebugHandleValue ** ppHandle);
9461
9462     //-----------------------------------------------------------
9463     // ICorDebugHeapValue3
9464     //-----------------------------------------------------------
9465     COM_METHOD GetThreadOwningMonitorLock(ICorDebugThread **ppThread, DWORD *pAcquisitionCount);
9466     COM_METHOD GetMonitorEventWaitList(ICorDebugThreadEnum **ppThreadEnum);
9467
9468     //-----------------------------------------------------------
9469     // ICorDebugGenericValue
9470     //-----------------------------------------------------------
9471
9472     COM_METHOD GetValue(void *pTo);
9473     COM_METHOD SetValue(void *pFrom);
9474
9475     //-----------------------------------------------------------
9476     // ICorDebugBoxValue
9477     //-----------------------------------------------------------
9478     COM_METHOD GetObject(ICorDebugObjectValue **ppObject);
9479
9480     // Returns a pointer to the ValueHome field
9481     virtual
9482     RemoteValueHome * GetValueHome() { return &m_valueHome; };
9483
9484     //-----------------------------------------------------------
9485     // Data members
9486     //-----------------------------------------------------------
9487
9488 private:
9489     SIZE_T          m_offsetToVars;
9490
9491     // remote location information
9492     RemoteValueHome m_valueHome;
9493
9494 };
9495
9496 /* ------------------------------------------------------------------------- *
9497  * Array Value class
9498  * ------------------------------------------------------------------------- */
9499
9500 class CordbArrayValue : public CordbValue, 
9501                         public ICorDebugArrayValue,
9502                         public ICorDebugGenericValue,
9503                         public ICorDebugValue2,
9504                         public ICorDebugValue3,
9505                         public ICorDebugHeapValue2,
9506                         public ICorDebugHeapValue3
9507 {
9508 public:
9509     CordbArrayValue(CordbAppDomain *          appdomain,
9510                     CordbType *               type,
9511                     DebuggerIPCE_ObjectData * pObjectInfo,
9512                     TargetBuffer              remoteValue);
9513     virtual ~CordbArrayValue();
9514
9515 #ifdef _DEBUG
9516     virtual const char * DbgGetName() { return "CordbArrayValue"; }
9517 #endif
9518
9519     //-----------------------------------------------------------
9520     // IUnknown
9521     //-----------------------------------------------------------
9522
9523     ULONG STDMETHODCALLTYPE AddRef()
9524     {
9525         return (BaseAddRef());
9526     }
9527     ULONG STDMETHODCALLTYPE Release()
9528     {
9529         return (BaseRelease());
9530     }
9531     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9532
9533     //-----------------------------------------------------------
9534     // ICorDebugValue
9535     //-----------------------------------------------------------
9536
9537     COM_METHOD GetType(CorElementType *pType)
9538     {
9539         return (CordbValue::GetType(pType));
9540     }
9541     COM_METHOD GetSize(ULONG32 *pSize)
9542     {
9543         return (CordbValue::GetSize(pSize));
9544     }
9545     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress)
9546     {
9547         VALIDATE_POINTER_TO_OBJECT(pAddress, CORDB_ADDRESS *);
9548         *pAddress = m_valueHome.GetAddress();
9549         return (S_OK);
9550     }
9551     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint)
9552     {
9553         return (CordbValue::CreateBreakpoint(ppBreakpoint));
9554     }
9555
9556     //-----------------------------------------------------------
9557     // ICorDebugValue2
9558     //-----------------------------------------------------------
9559
9560     COM_METHOD GetExactType(ICorDebugType **ppType)
9561     {
9562         return (CordbValue::GetExactType(ppType));
9563     }
9564
9565     //-----------------------------------------------------------
9566     // ICorDebugValue3
9567     //-----------------------------------------------------------
9568
9569     COM_METHOD GetSize64(ULONG64 *pSize)
9570     {
9571         return (CordbValue::GetSize64(pSize));
9572     }
9573
9574     //-----------------------------------------------------------
9575     // ICorDebugHeapValue
9576     //-----------------------------------------------------------
9577
9578     COM_METHOD IsValid(BOOL *pbValid);
9579     COM_METHOD CreateRelocBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint);
9580
9581     //-----------------------------------------------------------
9582     // ICorDebugHeapValue2
9583     //-----------------------------------------------------------
9584     COM_METHOD CreateHandle(CorDebugHandleType type, ICorDebugHandleValue ** ppHandle);
9585
9586     //-----------------------------------------------------------
9587     // ICorDebugHeapValue3
9588     //-----------------------------------------------------------
9589     COM_METHOD GetThreadOwningMonitorLock(ICorDebugThread **ppThread, DWORD *pAcquisitionCount);
9590     COM_METHOD GetMonitorEventWaitList(ICorDebugThreadEnum **ppThreadEnum);
9591
9592     //-----------------------------------------------------------
9593     // ICorDebugArrayValue
9594     //-----------------------------------------------------------
9595
9596     COM_METHOD GetElementType(CorElementType * pType);
9597     COM_METHOD GetRank(ULONG32 * pnRank);
9598     COM_METHOD GetCount(ULONG32 * pnCount);
9599     COM_METHOD GetDimensions(ULONG32 cdim, ULONG32 dims[]);
9600     COM_METHOD HasBaseIndicies(BOOL * pbHasBaseIndices);
9601     COM_METHOD GetBaseIndicies(ULONG32 cdim, ULONG32 indices[]);
9602     COM_METHOD GetElement(ULONG32 cdim, ULONG32 indices[], ICorDebugValue ** ppValue);
9603     COM_METHOD GetElementAtPosition(ULONG32 nIndex, ICorDebugValue ** ppValue);
9604
9605     //-----------------------------------------------------------
9606     // ICorDebugGenericValue
9607     //-----------------------------------------------------------
9608
9609     COM_METHOD GetValue(void *pTo);
9610     COM_METHOD SetValue(void *pFrom);
9611
9612     //-----------------------------------------------------------
9613     // Non-COM methods
9614     //-----------------------------------------------------------
9615
9616     HRESULT Init();
9617
9618     // Returns a pointer to the ValueHome field
9619     virtual
9620     RemoteValueHome * GetValueHome() { return &m_valueHome; };
9621
9622     //-----------------------------------------------------------
9623     // Data members
9624     //-----------------------------------------------------------
9625
9626 private:
9627     // contains information about the array, such as rank, number of elements, element size, etc.
9628     DebuggerIPCE_ObjectData  m_info;
9629
9630     // type of the elements
9631     CordbType               *m_elemtype;
9632
9633     // consists of three parts: a vector containing the lower bounds for each dimension,
9634     //                          a vector containing the upper bounds for each dimension,
9635     //                          a local cached copy of (part of) the array--initialized lazily when we 
9636     //                             request a particular element. If the array is large, we will store only
9637     //                             part of it, swapping out the cached segment as necessary to retrieve 
9638     //                             requested elements.
9639     BYTE *                   m_pObjectCopy;
9640
9641     // points to the beginning of the vector containing the lower bounds for each dimension in m_pObjectCopy
9642     DWORD *                  m_arrayLowerBase; 
9643
9644     // points to the beginning of the vector containing the lower bounds for each dimension in m_pObjectCopy
9645     DWORD *                  m_arrayUpperBase;
9646     // index of lower bound of data currently stored in m_pObjectCopy
9647     SIZE_T                   m_idxLower;
9648
9649     // index of upper bound of data currently stored in m_pObjectCopy
9650     SIZE_T                   m_idxUpper; 
9651
9652     // remote location information
9653     RemoteValueHome m_valueHome;
9654
9655 };
9656
9657 class CordbHandleValue : public CordbValue, public ICorDebugHandleValue, public ICorDebugValue2, public ICorDebugValue3
9658 {
9659 public:
9660     CordbHandleValue(CordbAppDomain *appdomain,
9661                      CordbType *type,
9662                      CorDebugHandleType handleType);
9663     HRESULT Init(VMPTR_OBJECTHANDLE pHandle);
9664
9665     virtual ~CordbHandleValue();
9666
9667     virtual void Neuter();
9668     virtual void NeuterLeftSideResources();
9669
9670 #ifdef _DEBUG
9671     virtual const char * DbgGetName() { return "CordbHandleValue"; }
9672 #endif
9673
9674
9675     //-----------------------------------------------------------
9676     // IUnknown
9677     //-----------------------------------------------------------
9678
9679     ULONG STDMETHODCALLTYPE AddRef()
9680     {
9681         return (BaseAddRef());
9682     }
9683     ULONG STDMETHODCALLTYPE Release()
9684     {
9685         return (BaseRelease());
9686     }
9687     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9688
9689     //-----------------------------------------------------------
9690     // ICorDebugHandleValue interface
9691     //-----------------------------------------------------------
9692     COM_METHOD GetHandleType(CorDebugHandleType *pType);
9693
9694
9695     /*
9696       * The final release of the interface will also dispose of the handle. This
9697       * API provides the ability for client to early dispose the handle.
9698       *
9699       */
9700     COM_METHOD Dispose();
9701
9702     //-----------------------------------------------------------
9703     // ICorDebugValue interface
9704     //-----------------------------------------------------------
9705     COM_METHOD GetType(CorElementType *pType);
9706     COM_METHOD GetSize(ULONG32 *pSize);
9707     COM_METHOD GetAddress(CORDB_ADDRESS *pAddress);
9708     COM_METHOD CreateBreakpoint(ICorDebugValueBreakpoint **ppBreakpoint);
9709
9710     //-----------------------------------------------------------
9711     // ICorDebugValue2
9712     //-----------------------------------------------------------
9713
9714     COM_METHOD GetExactType(ICorDebugType **ppType)
9715     {
9716         FAIL_IF_NEUTERED(this);
9717         
9718         // If AppDomain is already unloaded, return error
9719         if (m_appdomain->IsNeutered() == TRUE)
9720         {
9721             return COR_E_APPDOMAINUNLOADED;
9722         }
9723         if (m_vmHandle.IsNull())
9724         {
9725             return CORDBG_E_HANDLE_HAS_BEEN_DISPOSED;
9726         }
9727
9728         return (CordbValue::GetExactType(ppType));
9729     }
9730
9731     //-----------------------------------------------------------
9732     // ICorDebugValue3
9733     //-----------------------------------------------------------
9734
9735     COM_METHOD GetSize64(ULONG64 *pSize);
9736
9737     //-----------------------------------------------------------
9738     // ICorDebugReferenceValue interface
9739     //-----------------------------------------------------------
9740
9741     COM_METHOD IsNull(BOOL *pbNull);
9742     COM_METHOD GetValue(CORDB_ADDRESS *pValue);
9743     COM_METHOD SetValue(CORDB_ADDRESS value);
9744     COM_METHOD Dereference(ICorDebugValue **ppValue);
9745     COM_METHOD DereferenceStrong(ICorDebugValue **ppValue);
9746
9747     //-----------------------------------------------------------
9748     // Non-COM methods
9749     //-----------------------------------------------------------
9750
9751     // Returns a pointer to the ValueHome field
9752     virtual
9753     RemoteValueHome * GetValueHome() { return NULL; };
9754
9755 private:
9756     //BOOL RefreshHandleValue(void **pObjectToken);
9757     HRESULT RefreshHandleValue();
9758
9759     // EE object handle pointer. Can be casted to OBJECTHANDLE when go to LS
9760     // This instance owns the handle object and must call into the VM to release
9761     // it.
9762     // If this is non-null, then we increment code:CordbProces::IncrementOutstandingHandles.
9763     // Once it goes null, we should decrement the count.
9764     // Use AssignHandle, ClearHandle to keep this in sync.
9765     VMPTR_OBJECTHANDLE  m_vmHandle;         
9766
9767
9768     void AssignHandle(VMPTR_OBJECTHANDLE handle);
9769     void ClearHandle();
9770
9771     BOOL                m_fCanBeValid;      // true if object "can" be valid. False when object is no longer valid.
9772     CorDebugHandleType m_handleType;        // handle type can be strong or weak
9773     DebuggerIPCE_ObjectData  m_info;
9774 ; // ICORDebugClass of this object when we create the handle
9775 };
9776
9777 // This class actually has the implementation for ICorDebugHeap3 interfaces. Any value which implements
9778 // the interface just delegates to these static calls.
9779 class CordbHeapValue3Impl
9780 {
9781 public:
9782     static HRESULT GetThreadOwningMonitorLock(CordbProcess* pProcess,
9783                                               CORDB_ADDRESS remoteObjAddress,
9784                                               ICorDebugThread **ppThread,
9785                                               DWORD *pAcquistionCount);
9786     static HRESULT GetMonitorEventWaitList(CordbProcess* pProcess,
9787                                            CORDB_ADDRESS remoteObjAddress,
9788                                            ICorDebugThreadEnum **ppThreadEnum);
9789 };
9790
9791 /* ------------------------------------------------------------------------- *
9792  * Eval class
9793  * ------------------------------------------------------------------------- */
9794
9795 class CordbEval : public CordbBase, public ICorDebugEval, public ICorDebugEval2
9796 {
9797 public:
9798     CordbEval(CordbThread* pThread);
9799     virtual ~CordbEval();
9800
9801 #ifdef _DEBUG
9802     virtual const char * DbgGetName() { return "CordbEval"; }
9803 #endif
9804
9805     virtual void Neuter();
9806     virtual void NeuterLeftSideResources();
9807
9808     //-----------------------------------------------------------
9809     // IUnknown
9810     //-----------------------------------------------------------
9811
9812     ULONG STDMETHODCALLTYPE AddRef()
9813     {
9814         return (BaseAddRef());
9815     }
9816     ULONG STDMETHODCALLTYPE Release()
9817     {
9818         return (BaseRelease());
9819     }
9820     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
9821
9822     //-----------------------------------------------------------
9823     // ICorDebugEval
9824     //-----------------------------------------------------------
9825
9826     COM_METHOD CallFunction(ICorDebugFunction *pFunction,
9827                             ULONG32 nArgs,
9828                             ICorDebugValue *ppArgs[]);
9829     COM_METHOD NewObject(ICorDebugFunction *pConstructor,
9830                          ULONG32 nArgs,
9831                          ICorDebugValue *ppArgs[]);
9832     COM_METHOD NewObjectNoConstructor(ICorDebugClass *pClass);
9833     COM_METHOD NewString(LPCWSTR string);
9834     COM_METHOD NewArray(CorElementType elementType,
9835                         ICorDebugClass *pElementClass,
9836                         ULONG32 rank,
9837                         ULONG32 dims[],
9838                         ULONG32 lowBounds[]);
9839     COM_METHOD IsActive(BOOL *pbActive);
9840     COM_METHOD Abort();
9841     COM_METHOD GetResult(ICorDebugValue **ppResult);
9842     COM_METHOD GetThread(ICorDebugThread **ppThread);
9843     COM_METHOD CreateValue(CorElementType elementType,
9844                            ICorDebugClass *pElementClass,
9845                            ICorDebugValue **ppValue);
9846     COM_METHOD NewStringWithLength(LPCWSTR wszString, UINT iLength);
9847
9848     COM_METHOD CallParameterizedFunction(ICorDebugFunction * pFunction,
9849                                          ULONG32 nTypeArgs,
9850                                          ICorDebugType * rgpTypeArgs[],
9851                                          ULONG32 nArgs,
9852                                          ICorDebugValue * rgpArgs[]);
9853
9854     COM_METHOD CreateValueForType(ICorDebugType *pType,
9855                                   ICorDebugValue **ppValue);
9856
9857     COM_METHOD NewParameterizedObject(ICorDebugFunction * pConstructor,
9858                                       ULONG32 nTypeArgs,
9859                                       ICorDebugType * rgpTypeArgs[],
9860                                       ULONG32 nArgs,
9861                                       ICorDebugValue * rgpArgs[]);
9862
9863     COM_METHOD NewParameterizedObjectNoConstructor(ICorDebugClass * pClass,
9864                                                    ULONG32 nTypeArgs,
9865                                                    ICorDebugType * rgpTypeArgs[]);
9866
9867     COM_METHOD NewParameterizedArray(ICorDebugType * pElementType,
9868                                      ULONG32 rank,
9869                                      ULONG32 dims[],
9870                                      ULONG32 lowBounds[]);
9871
9872     //-----------------------------------------------------------
9873     // ICorDebugEval2
9874     //-----------------------------------------------------------
9875
9876     COM_METHOD RudeAbort();
9877
9878     //-----------------------------------------------------------
9879     // Non-COM methods
9880     //-----------------------------------------------------------
9881     HRESULT GatherArgInfo(ICorDebugValue *pValue,
9882                           DebuggerIPCE_FuncEvalArgData *argData);
9883     HRESULT SendCleanup();
9884
9885     // Create a RS literal for primitive type funceval result. In case the result is used as an argument for
9886     // another funceval, we need to make sure that we're not relying on the LS value, which will be freed and
9887     // thus unavailable. 
9888     HRESULT CreatePrimitiveLiteral(CordbType *       pType,
9889                                    ICorDebugValue ** ppValue);
9890
9891     //-----------------------------------------------------------
9892     // Data members
9893     //-----------------------------------------------------------
9894
9895     bool IsEvalDuringException() { return m_evalDuringException; }
9896 private:
9897     // We must keep a strong reference to the thread so we can properly fail out of SendCleanup if someone releases an
9898     // ICorDebugEval after the process has completely gone away. 
9899     RSSmartPtr<CordbThread>    m_thread;
9900     
9901     CordbFunction             *m_function;
9902     CordbClass                *m_class;
9903     DebuggerIPCE_FuncEvalType  m_evalType;
9904
9905     HRESULT SendFuncEval(unsigned int genericArgsCount, ICorDebugType *genericArgs[], void *argData1, unsigned int argData1Size, void *argData2, unsigned int argData2Size, DebuggerIPCEvent * event);
9906     HRESULT FilterHR(HRESULT hr);
9907     BOOL DoAppDomainsMatch( CordbAppDomain* pAppDomain, ULONG32 nTypes, ICorDebugType *pTypes[], ULONG32 nValues, ICorDebugValue *pValues[] );
9908
9909 public:
9910     bool                       m_complete;
9911     bool                       m_successful;
9912     bool                       m_aborted;
9913     void                      *m_resultAddr;
9914
9915     // This is an OBJECTHANDLE on the LS if func-eval creates a strong handle.
9916     // This is a resource in the left-side and must be cleaned up in the left-side.
9917     // This gets handled off to a CordbHandleValue (m_pHandleValue) once code:CordbEval::GetResult
9918     // and then the CordbHandle is responsible for releasing it in the left-side.
9919     // Issue!! This will be leaked if nobody calls GetResult().
9920     VMPTR_OBJECTHANDLE         m_vmObjectHandle;          
9921
9922     // This is the corresponding cached CordbHandleValue for GetResult.
9923     // This takes ownership of the strong handle, m_objectHandle. 
9924     // This is an External reference, which keeps the Value from being neutered
9925     // on a NeuterAtWill sweep.
9926     RSExtSmartPtr<CordbHandleValue> m_pHandleValue;          
9927
9928     DebuggerIPCE_ExpandedTypeData m_resultType;
9929     VMPTR_AppDomain            m_resultAppDomainToken;
9930
9931     // Left-side memory that needs to be freed.
9932     LSPTR_DEBUGGEREVAL         m_debuggerEvalKey;
9933
9934
9935     // If we're evalling during a thread's exception, remember the info so that we can restore it when we're done.
9936     bool                       m_evalDuringException;     // flag whether we're during the thread's exception.
9937     VMPTR_OBJECTHANDLE  m_vmThreadOldExceptionHandle; // object handle for thread's managed exception object.
9938
9939 #ifdef _DEBUG
9940     // Func-eval should perturb the the thread's current appdomain. So we remember it at start
9941     // and then ensure that the func-eval complete restores it.
9942     CordbAppDomain *           m_DbgAppDomainStarted;
9943 #endif
9944 };
9945
9946
9947 /* ------------------------------------------------------------------------- *
9948  * Win32 Event Thread class
9949  * ------------------------------------------------------------------------- */
9950 const unsigned int CW32ET_UNKNOWN_PROCESS_SLOT = 0xFFffFFff; // it's a managed process,
9951         //but we don't know which slot it's in - for Detach.
9952
9953 //---------------------------------------------------------------------------------------
9954 //
9955 // Dedicated thread for win32 debugging operations.
9956 //
9957 // Notes:
9958 //    This is owned by the ShimProcess object. That will both create this and destroy it.
9959 //    OS restriction is that all win32 debugging APIs (CreateProcess, DebugActiveProcess,
9960 //    DebugActiveProcessStop, WaitForDebugEvent, ContinueDebugEvent, etc) are on the same thread.
9961 //
9962 class CordbWin32EventThread
9963 {
9964     friend class CordbProcess; //so that Detach can call ExitProcess
9965 public:
9966     CordbWin32EventThread(Cordb * pCordb, ShimProcess * pShim);
9967     virtual ~CordbWin32EventThread();
9968
9969     //
9970     // You create a new instance of this class, call Init() to set it up,
9971     // then call Start() start processing events. Stop() terminates the
9972     // thread and deleting the instance cleans all the handles and such
9973     // up.
9974     //
9975     HRESULT Init();
9976     HRESULT Start();
9977     HRESULT Stop();
9978
9979     HRESULT SendCreateProcessEvent(MachineInfo machineInfo,
9980                                    LPCWSTR programName,
9981                                    __in_z LPWSTR  programArgs,
9982                                    LPSECURITY_ATTRIBUTES lpProcessAttributes,
9983                                    LPSECURITY_ATTRIBUTES lpThreadAttributes,
9984                                    BOOL bInheritHandles,
9985                                    DWORD dwCreationFlags,
9986                                    PVOID lpEnvironment,
9987                                    LPCWSTR lpCurrentDirectory,
9988                                    LPSTARTUPINFOW lpStartupInfo,
9989                                    LPPROCESS_INFORMATION lpProcessInformation,
9990                                    CorDebugCreateProcessFlags corDebugFlags);
9991
9992     HRESULT SendDebugActiveProcessEvent(MachineInfo machineInfo,
9993                                         DWORD pid,
9994                                         bool fWin32Attach,
9995                                         CordbProcess *pProcess);
9996
9997     HRESULT SendDetachProcessEvent(CordbProcess *pProcess);
9998
9999 #ifdef FEATURE_INTEROP_DEBUGGING
10000     HRESULT SendUnmanagedContinue(CordbProcess *pProcess,
10001                                   EUMContinueType eContType);
10002     HRESULT UnmanagedContinue(CordbProcess *pProcess,
10003                               EUMContinueType eContType);
10004     void DoDbgContinue(CordbProcess * pProcess,
10005                        CordbUnmanagedEvent * pUnmanagedEvent);
10006     void ForceDbgContinue(CordbProcess *pProcess,
10007                           CordbUnmanagedThread *ut,
10008                           DWORD contType,
10009                           bool contProcess);
10010
10011 #endif //FEATURE_INTEROP_DEBUGGING
10012
10013     void LockSendToWin32EventThreadMutex()
10014     {
10015         LOG((LF_CORDB, LL_INFO10000, "W32ET::LockSendToWin32EventThreadMutex\n"));
10016         m_sendToWin32EventThreadMutex.Lock();
10017     }
10018
10019     void UnlockSendToWin32EventThreadMutex()
10020     {
10021         m_sendToWin32EventThreadMutex.Unlock();
10022         LOG((LF_CORDB, LL_INFO10000, "W32ET::UnlockSendToWin32EventThreadMutex\n"));
10023     }
10024
10025     bool IsWin32EventThread()
10026     {
10027         return (m_threadId == GetCurrentThreadId());
10028     }
10029
10030     void Win32EventLoop();
10031
10032
10033     INativeEventPipeline * GetNativePipeline();
10034 private:
10035     void ThreadProc();
10036     static DWORD WINAPI ThreadProc(LPVOID parameter);
10037
10038     void CreateProcess();
10039
10040
10041     INativeEventPipeline * m_pNativePipeline;
10042
10043
10044     void AttachProcess();
10045
10046     void HandleUnmanagedContinue();
10047
10048     void ExitProcess(bool fDetach);
10049
10050 private:
10051     RSSmartPtr<Cordb>    m_cordb;
10052
10053     HANDLE               m_thread;
10054     DWORD                m_threadId;
10055     HANDLE               m_threadControlEvent;
10056     HANDLE               m_actionTakenEvent;
10057     BOOL                 m_run;
10058
10059     // The process that we're 1:1 with.
10060     // This is set when we get a Create / Attach event.
10061     // This is only used on the W32ET, which guarantees it will free of races.
10062     RSSmartPtr<CordbProcess> m_pProcess;
10063
10064
10065     ShimProcess * m_pShim;
10066
10067     // @todo - convert this into Stop-Go lock?
10068     RSLock               m_sendToWin32EventThreadMutex;
10069
10070     unsigned int         m_action;
10071     HRESULT              m_actionResult;
10072     union
10073     {
10074         struct
10075         {
10076             MachineInfo machineInfo;
10077             LPCWSTR programName;
10078             LPWSTR  programArgs;
10079             LPSECURITY_ATTRIBUTES lpProcessAttributes;
10080             LPSECURITY_ATTRIBUTES lpThreadAttributes;
10081             BOOL bInheritHandles;
10082             DWORD dwCreationFlags;
10083             PVOID lpEnvironment;
10084             LPCWSTR lpCurrentDirectory;
10085             LPSTARTUPINFOW lpStartupInfo;
10086             LPPROCESS_INFORMATION lpProcessInformation;
10087             CorDebugCreateProcessFlags corDebugFlags;
10088         } createData;
10089
10090         struct
10091         {
10092             MachineInfo     machineInfo;
10093             DWORD           processId;
10094 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
10095             bool            fWin32Attach;
10096 #endif
10097             CordbProcess    *pProcess;
10098
10099             // Wrapper to determine if we're interop-debugging.
10100             bool IsInteropDebugging()
10101             {
10102 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
10103                 return fWin32Attach;
10104 #else
10105                 return false;
10106 #endif
10107             }
10108         } attachData;
10109
10110         struct
10111         {
10112             CordbProcess    *pProcess;
10113         } detachData;
10114
10115         struct
10116         {
10117             CordbProcess *process;
10118             EUMContinueType eContType;
10119         } continueData;
10120     }                    m_actionData;
10121 };
10122
10123
10124 // Thread-safe stack which.
10125 template <typename T>
10126 class InterlockedStack
10127 {
10128 public:
10129     InterlockedStack();
10130     ~InterlockedStack();
10131
10132     // Thread safe pushes + pops.
10133     // Many threads can push simultaneously.
10134     // Only 1 thread can pop.
10135     void Push(T * pItem);
10136     T * Pop();
10137
10138 protected:
10139     T * m_pHead;
10140 };
10141
10142 //-----------------------------------------------------------------------------
10143 // Workitem to be placed on RCET worker queue.
10144 // There's 1 RCET for to be shared by all processes.
10145 //-----------------------------------------------------------------------------
10146 class RCETWorkItem
10147 {
10148 public:
10149
10150     // Item is executed and then removed from the list and deleted.
10151     virtual void Do() = 0;
10152
10153     CordbProcess * GetProcess() { return m_pProcess; }
10154
10155 protected:
10156     RCETWorkItem(CordbProcess * pProcess)
10157     {
10158         m_pProcess.Assign(pProcess);
10159         m_next = NULL;
10160     }
10161
10162     RSSmartPtr<CordbProcess> m_pProcess;
10163
10164     // This field is accessed by the InterlockedStack.
10165     friend class InterlockedStack<RCETWorkItem>;
10166     RCETWorkItem * m_next;
10167 };
10168
10169
10170 // Item to do Neutering work on ExitProcess.
10171 class ExitProcessWorkItem : public RCETWorkItem
10172 {
10173 public:
10174     ExitProcessWorkItem(CordbProcess * pProc) : RCETWorkItem(pProc)
10175     {
10176     }
10177
10178     virtual void Do();
10179 };
10180
10181 // Item to do send Attach event.
10182 class SendAttachProcessWorkItem : public RCETWorkItem
10183 {
10184 public:
10185     SendAttachProcessWorkItem(CordbProcess * pProc) : RCETWorkItem(pProc)
10186     {
10187     }
10188
10189     virtual void Do();
10190 };
10191
10192
10193 /* ------------------------------------------------------------------------- *
10194  * Runtime Controller Event Thread class
10195  * ------------------------------------------------------------------------- */
10196
10197 class CordbRCEventThread
10198 {
10199 public:
10200     CordbRCEventThread(Cordb* cordb);
10201     virtual ~CordbRCEventThread();
10202
10203     //
10204     // You create a new instance of this class, call Init() to set it up,
10205     // then call Start() start processing events. Stop() terminates the
10206     // thread and deleting the instance cleans all the handles and such
10207     // up.
10208     //
10209     HRESULT Init();
10210     HRESULT Start();
10211     HRESULT Stop();
10212
10213     // RCET will take ownership of this item and delete it.
10214     void QueueAsyncWorkItem(RCETWorkItem * pItem);
10215
10216     HRESULT SendIPCEvent(CordbProcess* process,
10217                          DebuggerIPCEvent* event,
10218                          SIZE_T eventSize);
10219
10220     void ProcessStateChanged();
10221     void FlushQueuedEvents(CordbProcess* process);
10222
10223     HRESULT WaitForIPCEventFromProcess(CordbProcess* process,
10224                                        CordbAppDomain *pAppDomain,
10225                                        DebuggerIPCEvent* event);
10226
10227     bool IsRCEventThread();
10228
10229 private:
10230     void DrainWorkerQueue();
10231
10232     void ThreadProc();
10233     static DWORD WINAPI ThreadProc(LPVOID parameter);
10234
10235
10236 private:
10237     InterlockedStack<class RCETWorkItem> m_WorkerStack;
10238
10239     RSSmartPtr<Cordb>    m_cordb;
10240     HANDLE               m_thread;
10241     DWORD                m_threadId;
10242     BOOL                 m_run;
10243     HANDLE               m_threadControlEvent;
10244     BOOL                 m_processStateChanged;
10245 };
10246
10247 #ifdef FEATURE_INTEROP_DEBUGGING
10248 /* ------------------------------------------------------------------------- *
10249  * Unmanaged Event struct
10250  * ------------------------------------------------------------------------- */
10251
10252 enum CordbUnmanagedEventState
10253 {
10254
10255     // The continued flags get set in one of a few patterns.
10256     // 1) The event is continued having never been hijacked =>
10257     //      EventContinuedUnhijacked is set
10258     // 2) The event is continued having been hijacked and then the process terminates or
10259     //    an error occurs before the hijack finishes =>
10260     //      EventContinuedHijacked is set
10261     // 3) The event is continued having been hijacked, then the hijack completes and
10262     //    execution resumes in the debuggee
10263     //      EventContinuedHijacked is set
10264     //      EventContinuedUnhijacked is set
10265
10266     CUES_None                     = 0x00,
10267     CUES_ExceptionCleared         = 0x01,
10268     CUES_EventContinuedHijacked   = 0x02,
10269     CUES_EventContinuedUnhijacked = 0x04,
10270     CUES_Dispatched               = 0x08,
10271     CUES_ExceptionUnclearable     = 0x10,
10272
10273     // This is set when a user continues the event by calling
10274     // Continue()
10275     CUES_UserContinued            = 0x20,
10276     // This is true if the event is an IB event
10277     CUES_IsIBEvent                = 0x40,
10278 };
10279
10280 struct CordbUnmanagedEvent
10281 {
10282 public:
10283     BOOL IsExceptionCleared() { return m_state & CUES_ExceptionCleared; }
10284     BOOL IsEventContinuedHijacked() { return m_state & CUES_EventContinuedHijacked; }
10285     BOOL IsEventContinuedUnhijacked() { return m_state & CUES_EventContinuedUnhijacked; }
10286     BOOL IsEventUserContinued() { return m_state & CUES_UserContinued; }
10287     BOOL IsEventWaitingForContinue()
10288     {
10289         return (!IsEventContinuedHijacked() && !IsEventContinuedUnhijacked());
10290     }
10291     BOOL IsDispatched() { return m_state & CUES_Dispatched; }
10292     BOOL IsExceptionUnclearable() { return m_state & CUES_ExceptionUnclearable; }
10293     BOOL IsIBEvent() { return m_state & CUES_IsIBEvent; }
10294
10295     void SetState(CordbUnmanagedEventState state) { m_state = (CordbUnmanagedEventState)(m_state | state); }
10296     void ClearState(CordbUnmanagedEventState state) { m_state = (CordbUnmanagedEventState)(m_state & ~state); }
10297
10298     CordbUnmanagedThread     *m_owner;
10299     CordbUnmanagedEventState  m_state;
10300     DEBUG_EVENT               m_currentDebugEvent;
10301     CordbUnmanagedEvent      *m_next;
10302 };
10303
10304
10305 /* ------------------------------------------------------------------------- *
10306  * Unmanaged Thread class
10307  * ------------------------------------------------------------------------- */
10308
10309 enum CordbUnmanagedThreadState
10310 {
10311     CUTS_None                        = 0x0000,
10312     CUTS_Deleted                     = 0x0001,
10313     CUTS_FirstChanceHijacked         = 0x0002,
10314     // Set when interop debugging needs the SS flag to be enabled
10315     // regardless of what the user wants it to be
10316     CUTS_IsSSFlagNeeded              = 0x0004,
10317     CUTS_GenericHijacked             = 0x0008,
10318     // when the m_raiseExceptionEntryContext is valid
10319     CUTS_HasRaiseExceptionEntryCtx   = 0x0010,
10320     CUTS_BlockingForSync             = 0x0020,
10321     CUTS_Suspended                   = 0x0040,
10322     CUTS_IsSpecialDebuggerThread     = 0x0080,
10323     // when the thread is re-executing RaiseException to retrigger an exception
10324     CUTS_IsRaiseExceptionHijacked    = 0x0100,
10325     CUTS_HasIBEvent                  = 0x0200,
10326     CUTS_HasOOBEvent                 = 0x0400,
10327     CUTS_HasSpecialStackOverflowCase = 0x0800,
10328 #ifdef _DEBUG
10329     CUTS_DEBUG_SingleStep            = 0x1000,
10330 #endif
10331     CUTS_SkippingNativePatch         = 0x2000,
10332     CUTS_HasContextSet               = 0x4000,
10333     // Set when interop debugging is making use of the single step flag
10334     // but the user has not set it
10335     CUTS_IsSSFlagHidden              = 0x8000
10336     
10337 };
10338
10339 class CordbUnmanagedThread : public CordbBase
10340 {
10341 public:
10342     CordbUnmanagedThread(CordbProcess *pProcess, DWORD dwThreadId, HANDLE hThread, void *lpThreadLocalBase);
10343     ~CordbUnmanagedThread();
10344
10345     using CordbBase::GetProcess;
10346
10347 #ifdef _DEBUG
10348     virtual const char * DbgGetName() { return "CordbUnmanagedThread"; }
10349 #endif
10350
10351     // CordbUnmanagedThread is a purely internal object. It's not exposed via ICorDebug APIs and so
10352     // we should never use External AddRef.
10353     ULONG STDMETHODCALLTYPE AddRef() { _ASSERTE(!"Don't use external addref on a CordbUnmanagedThread"); return (BaseAddRef());}
10354     ULONG STDMETHODCALLTYPE Release() { _ASSERTE(!"Don't use external release on a CordbUnmanagedThread"); return (BaseRelease());}
10355
10356     COM_METHOD QueryInterface(REFIID riid, void **ppInterface)
10357     {
10358         _ASSERTE(!"Don't use QI on a CordbUnmanagedThread");
10359         // Not really used since we never expose this class. If we ever do expose this class via the ICorDebug API then
10360         // we should, of course, implement this.
10361         return E_NOINTERFACE;
10362     }
10363
10364     HRESULT LoadTLSArrayPtr();
10365
10366     // Hijacks this thread to a hijack worker function which recieves the current
10367     // context and the provided exception record. The reason determines what code
10368     // the hijack worker executes
10369     HRESULT SetupFirstChanceHijack(EHijackReason::EHijackReason reason, const EXCEPTION_RECORD * pExceptionRecord);
10370     HRESULT SetupFirstChanceHijackForSync();
10371
10372     HRESULT SetupGenericHijack(DWORD eventCode, const EXCEPTION_RECORD * pRecord);
10373     HRESULT FixupFromGenericHijack();
10374
10375     HRESULT FixupAfterOOBException(CordbUnmanagedEvent * ue);
10376
10377     void SetupForSkipBreakpoint(NativePatch * pNativePatch);
10378     void FixupForSkipBreakpoint();
10379     bool IsCantStop();
10380
10381     // These are wrappers for the OS calls which hide
10382     // the effects of hijacking and internal SS flag usage
10383     HRESULT GetThreadContext(DT_CONTEXT * pContext);
10384     HRESULT SetThreadContext(DT_CONTEXT * pContext);
10385
10386     // Turns on and off the internal usage of the SS flag
10387     VOID BeginStepping();
10388     VOID EndStepping();
10389
10390     // An accessor for &m_context, this value generally stores
10391     // a context we may need to restore after a hijack completes
10392     DT_CONTEXT * GetHijackCtx();
10393
10394 private:
10395     CORDB_ADDRESS m_stackBase;
10396     CORDB_ADDRESS m_stackLimit;
10397
10398 public:
10399     BOOL GetStackRange(CORDB_ADDRESS *pBase, CORDB_ADDRESS *pLimit);
10400
10401     BOOL IsDeleted() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_Deleted; }
10402     BOOL IsFirstChanceHijacked() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_FirstChanceHijacked; }
10403     BOOL IsGenericHijacked() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_GenericHijacked; }
10404     BOOL IsBlockingForSync() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_BlockingForSync; }
10405     BOOL IsSuspended() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_Suspended; }
10406     BOOL IsSpecialDebuggerThread() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_IsSpecialDebuggerThread; }
10407     BOOL HasIBEvent() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_HasIBEvent; }
10408     BOOL HasOOBEvent() { return m_state & CUTS_HasOOBEvent; }
10409     BOOL HasSpecialStackOverflowCase() {LIMITED_METHOD_CONTRACT;  return m_state & CUTS_HasSpecialStackOverflowCase; }
10410 #ifdef _DEBUG
10411     BOOL IsDEBUGTrace() { return m_state & CUTS_DEBUG_SingleStep; }
10412 #endif
10413     BOOL IsSkippingNativePatch() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_SkippingNativePatch; }
10414     BOOL IsContextSet() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_HasContextSet; }
10415     BOOL IsSSFlagNeeded() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_IsSSFlagNeeded; }
10416     BOOL IsSSFlagHidden() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_IsSSFlagHidden; }
10417     BOOL HasRaiseExceptionEntryCtx() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_HasRaiseExceptionEntryCtx; }
10418     BOOL IsRaiseExceptionHijacked() { LIMITED_METHOD_CONTRACT; return m_state & CUTS_IsRaiseExceptionHijacked; }
10419
10420     void SetState(CordbUnmanagedThreadState state) 
10421     {
10422         LIMITED_METHOD_CONTRACT;  
10423         m_state = (CordbUnmanagedThreadState)(m_state | state); 
10424         _ASSERTE(!IsSuspended() || !IsBlockingForSync());
10425         _ASSERTE(!IsSuspended() || !IsFirstChanceHijacked());
10426     }
10427     void ClearState(CordbUnmanagedThreadState state) {LIMITED_METHOD_CONTRACT;  m_state = (CordbUnmanagedThreadState)(m_state & ~state); }
10428
10429     void HijackToRaiseException();
10430     void RestoreFromRaiseExceptionHijack();
10431     void SaveRaiseExceptionEntryContext();
10432     void ClearRaiseExceptionEntryContext();
10433     BOOL IsExceptionFromLastRaiseException(const EXCEPTION_RECORD* pExceptionRecord);
10434
10435     CordbUnmanagedEvent *IBEvent()  {LIMITED_METHOD_CONTRACT;  return &m_IBEvent; }
10436     CordbUnmanagedEvent *IBEvent2() {LIMITED_METHOD_CONTRACT;  return &m_IBEvent2; }
10437     CordbUnmanagedEvent *OOBEvent() { return &m_OOBEvent; }
10438
10439     DWORD GetOSTid() 
10440     { 
10441         return (DWORD) this->m_id; 
10442     }
10443
10444 #ifdef DBG_TARGET_X86
10445     // Stores the thread's current leaf SEH handler
10446     HRESULT SaveCurrentLeafSeh();
10447     // Restores the thread's leaf SEH handler from the previously saved value
10448     HRESULT RestoreLeafSeh();
10449 #endif
10450
10451     // Logs basic data about a context to the debugging log
10452     static VOID LogContext(DT_CONTEXT* pContext);
10453
10454 public:
10455     HANDLE                     m_handle;
10456
10457     // @dbgtodo - the TLS reading is only used for interop hijacks; which goes away in Arrowhead.
10458     // Target address of the Thread Information Block (TIB).
10459     void                      *m_threadLocalBase;
10460     
10461     // Target address of the Thread Local Storage (TLS) array. This is for slots 0 -63.
10462     void                      *m_pTLSArray;
10463
10464     // Target Address of extended Thread local Storage array. These are for slots about 63.
10465     // This may be NULL if extended storage is not yet allocated.
10466     void                      *m_pTLSExtendedArray;
10467
10468
10469     CordbUnmanagedThreadState  m_state;
10470
10471     CordbUnmanagedEvent        m_IBEvent;
10472     CordbUnmanagedEvent        m_IBEvent2;
10473     CordbUnmanagedEvent        m_OOBEvent;
10474
10475     LSPTR_CONTEXT              m_pLeftSideContext;
10476     void                      *m_originalHandler;
10477
10478 private:
10479     // Spare context used for various purposes. 
10480     // See CordbUnmanagedThread::GetThreadContext for details
10481     DT_CONTEXT                 m_context;
10482
10483     // The context of the thread the last time it called into kernel32!RaiseException
10484     DT_CONTEXT                 m_raiseExceptionEntryContext;
10485
10486     DWORD                      m_raiseExceptionExceptionCode;
10487     DWORD                      m_raiseExceptionExceptionFlags;
10488     DWORD                      m_raiseExceptionNumberParameters;
10489     ULONG_PTR                  m_raiseExceptionExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
10490
10491
10492 #ifdef DBG_TARGET_X86
10493     // the SEH handler which was the leaf when SaveCurrentSeh was called (prior to hijack)
10494     REMOTE_PTR                 m_pSavedLeafSeh;
10495 #endif
10496
10497     HRESULT EnableSSAfterBP();
10498     bool GetEEThreadCantStopHelper();
10499
10500     DWORD_PTR GetTlsSlot(SIZE_T slot);
10501     REMOTE_PTR GetPreDefTlsSlot(SIZE_T slot, bool * pRead);
10502
10503     void * m_pPatchSkipAddress;
10504
10505
10506
10507     /* 
10508      * This abstracts away an overload of the OS thread's TLS slot. In 
10509      * particular the runtime may or may not have created a thread object for
10510      * a particular OS thread at any point.
10511      *
10512      * If the runtime has created a thread object, then it stores a pointer to
10513      * that thread object in the thread's TLS slot.
10514      *
10515      * If not, then interop-debugging uses that TLS slot to store temporary 
10516      * information.
10517      *
10518      * To determine this, interop-debugging will set the low bit.  Thus when
10519      * we read the TLS slot, if it is non-NULL, anything w/o the low bit set
10520      * is an EE thread object ptr.  Anything with the low bit set is an 
10521      * interop-debugging value.  Any NULL is null, and an indicator that 
10522      * there does not exist a runtime thread object for this thread yet.
10523      *
10524      */
10525     REMOTE_PTR m_pEEThread;
10526     REMOTE_PTR m_pdwTlsValue;
10527     BOOL m_fValidTlsData;
10528
10529     UINT m_continueCountCached;
10530
10531     void CacheEEDebuggerWord();
10532     HRESULT SetEEThreadValue(REMOTE_PTR EETlsValue);
10533 #ifdef FEATURE_IMPLICIT_TLS
10534     DWORD_PTR GetEEThreadValue();
10535     REMOTE_PTR GetClrModuleTlsDataAddress();
10536     REMOTE_PTR GetEETlsDataBlock();
10537 #endif
10538
10539 public:
10540     HRESULT GetEEDebuggerWord(REMOTE_PTR *pValue);
10541     HRESULT SetEEDebuggerWord(REMOTE_PTR value);
10542     HRESULT GetEEThreadPtr(REMOTE_PTR *ppEEThread);
10543     
10544     bool GetEEPGCDisabled();
10545     void GetEEState(bool *threadStepping, bool *specialManagedException);
10546     bool GetEEFrame();
10547 };
10548 #endif // FEATURE_INTEROP_DEBUGGING
10549
10550
10551 //********************************************************************************
10552 //**************** App Domain Publishing Service API *****************************
10553 //********************************************************************************
10554
10555
10556 class EnumElement
10557 {
10558 public:
10559     EnumElement()
10560     {
10561         m_pData = NULL;
10562         m_pNext = NULL;
10563     }
10564
10565     void SetData (void *pData) { m_pData = pData;}
10566     void *GetData () { return m_pData;}
10567     void SetNext (EnumElement *pNext) { m_pNext = pNext;}
10568     EnumElement *GetNext () { return m_pNext;}
10569
10570 private:
10571     void        *m_pData;
10572     EnumElement *m_pNext;
10573 };
10574
10575 #if defined(FEATURE_DBG_PUBLISH)
10576
10577 // Prototype of psapi!GetModuleFileNameEx.
10578 typedef DWORD FPGetModuleFileNameEx(HANDLE, HMODULE, LPTSTR, DWORD);
10579
10580
10581 class CorpubPublish : public CordbCommonBase, public ICorPublish
10582 {
10583 public:
10584     CorpubPublish();
10585     virtual ~CorpubPublish();
10586
10587 #ifdef _DEBUG
10588     virtual const char * DbgGetName() { return "CordbPublish"; }
10589 #endif
10590
10591     //-----------------------------------------------------------
10592     // IUnknown
10593     //-----------------------------------------------------------
10594
10595     ULONG STDMETHODCALLTYPE AddRef()
10596     {
10597         return (BaseAddRef());
10598     }
10599     ULONG STDMETHODCALLTYPE Release()
10600     {
10601         return (BaseRelease());
10602     }
10603     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10604
10605     //-----------------------------------------------------------
10606     // ICorPublish
10607     //-----------------------------------------------------------
10608
10609     COM_METHOD EnumProcesses(
10610         COR_PUB_ENUMPROCESS Type,
10611         ICorPublishProcessEnum **ppIEnum);
10612
10613     COM_METHOD GetProcess(
10614         unsigned pid,
10615         ICorPublishProcess **ppProcess);
10616
10617     //-----------------------------------------------------------
10618     // CreateObject
10619     //-----------------------------------------------------------
10620     static COM_METHOD CreateObject(REFIID id, void **object)
10621     {
10622         *object = NULL;
10623
10624         if (id != IID_IUnknown && id != IID_ICorPublish)
10625             return (E_NOINTERFACE);
10626
10627         CorpubPublish *pCorPub = new (nothrow) CorpubPublish();
10628
10629         if (pCorPub == NULL)
10630             return (E_OUTOFMEMORY);
10631
10632         *object = (ICorPublish*)pCorPub;
10633         pCorPub->AddRef();
10634
10635         return (S_OK);
10636     }
10637
10638 private:
10639     HRESULT GetProcessInternal( unsigned pid, CorpubProcess **ppProcess );
10640
10641     // Cached information to get the process name. Not available on all platforms, so may be null.
10642     HModuleHolder m_hPSAPIdll;
10643     FPGetModuleFileNameEx * m_fpGetModuleFileNameEx;
10644 };
10645
10646 class CorpubProcess : public CordbCommonBase, public ICorPublishProcess
10647 {
10648 public:
10649     CorpubProcess(DWORD dwProcessId, 
10650         bool fManaged, 
10651         HANDLE hProcess,
10652         HANDLE hMutex, 
10653         AppDomainEnumerationIPCBlock *pAD, 
10654 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
10655         IPCReaderInterface *pIPCReader, 
10656 #endif // !FEATURE_DBGIPC_TRANSPORT_DI
10657         FPGetModuleFileNameEx * fpGetModuleFileNameEx);
10658     virtual ~CorpubProcess();
10659
10660 #ifdef _DEBUG
10661     virtual const char * DbgGetName() { return "CorpubProcess"; }
10662 #endif
10663
10664
10665     //-----------------------------------------------------------
10666     // IUnknown
10667     //-----------------------------------------------------------
10668
10669     ULONG STDMETHODCALLTYPE AddRef()
10670     {
10671         return (BaseAddRef());
10672     }
10673     ULONG STDMETHODCALLTYPE Release()
10674     {
10675         return (BaseRelease());
10676     }
10677     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10678
10679     //-----------------------------------------------------------
10680     // ICorPublishProcess
10681     //-----------------------------------------------------------
10682     COM_METHOD IsManaged(BOOL *pbManaged);
10683
10684     /*
10685      * Enumerate the list of known application domains in the target process.
10686      */
10687     COM_METHOD EnumAppDomains(ICorPublishAppDomainEnum **ppEnum);
10688
10689     /*
10690      * Returns the OS ID for the process in question.
10691      */
10692     COM_METHOD GetProcessID(unsigned *pid);
10693
10694     /*
10695      * Get the display name for a process.
10696      */
10697     COM_METHOD GetDisplayName(ULONG32 cchName,
10698                                 ULONG32 *pcchName,
10699                                 __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
10700
10701     CorpubProcess   *GetNextProcess () { return m_pNext;}
10702     void SetNext (CorpubProcess *pNext) { m_pNext = pNext;}
10703
10704     // Helper to tell if this process has exited
10705     bool IsExited();
10706
10707 public:
10708     DWORD                           m_dwProcessId;
10709
10710 private:
10711     bool                            m_fIsManaged;
10712     HANDLE                          m_hProcess;
10713     HANDLE                          m_hMutex;
10714     AppDomainEnumerationIPCBlock    *m_AppDomainCB;
10715 #if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
10716     IPCReaderInterface              *m_pIPCReader;  // controls the lifetime of the AppDomainEnumerationIPCBlock
10717 #endif // !FEATURE_DBGIPC_TRANSPORT_DI
10718     CorpubProcess                   *m_pNext;   // pointer to the next process in the process list
10719     WCHAR                           *m_szProcessName;
10720
10721 };
10722
10723 class CorpubAppDomain  : public CordbCommonBase, public ICorPublishAppDomain
10724 {
10725 public:
10726     CorpubAppDomain (__in LPWSTR szAppDomainName, ULONG Id);
10727     virtual ~CorpubAppDomain();
10728
10729 #ifdef _DEBUG
10730     virtual const char * DbgGetName() { return "CorpubAppDomain"; }
10731 #endif
10732
10733     //-----------------------------------------------------------
10734     // IUnknown
10735     //-----------------------------------------------------------
10736
10737     ULONG STDMETHODCALLTYPE AddRef()
10738     {
10739         return (BaseAddRef());
10740     }
10741     ULONG STDMETHODCALLTYPE Release()
10742     {
10743         return (BaseRelease());
10744     }
10745     COM_METHOD QueryInterface (REFIID riid, void **ppInterface);
10746
10747     //-----------------------------------------------------------
10748     // ICorPublishAppDomain
10749     //-----------------------------------------------------------
10750
10751     /*
10752      * Get the name and ID for an application domain.
10753      */
10754     COM_METHOD GetID (ULONG32 *pId);
10755
10756     /*
10757      * Get the name for an application domain.
10758      */
10759     COM_METHOD GetName (ULONG32 cchName,
10760                         ULONG32 *pcchName,
10761                         __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
10762
10763     CorpubAppDomain *GetNextAppDomain () { return m_pNext;}
10764     void SetNext (CorpubAppDomain *pNext) { m_pNext = pNext;}
10765
10766 private:
10767     CorpubAppDomain *m_pNext;
10768     WCHAR           *m_szAppDomainName;
10769     ULONG           m_id;
10770
10771 };
10772
10773 class CorpubProcessEnum : public CordbCommonBase, public ICorPublishProcessEnum
10774 {
10775 public:
10776     CorpubProcessEnum(CorpubProcess *pFirst);
10777     virtual ~CorpubProcessEnum();
10778
10779 #ifdef _DEBUG
10780     virtual const char * DbgGetName() { return "CorpubProcessEnum"; }
10781 #endif
10782
10783
10784     //-----------------------------------------------------------
10785     // IUnknown
10786     //-----------------------------------------------------------
10787
10788     ULONG STDMETHODCALLTYPE AddRef()
10789     {
10790         return (BaseAddRef());
10791     }
10792     ULONG STDMETHODCALLTYPE Release()
10793     {
10794         return (BaseRelease());
10795     }
10796     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10797
10798     //-----------------------------------------------------------
10799     // ICorPublishProcessEnum
10800     //-----------------------------------------------------------
10801
10802     COM_METHOD Skip(ULONG celt);
10803     COM_METHOD Reset();
10804     COM_METHOD Clone(ICorPublishEnum **ppEnum);
10805     COM_METHOD GetCount(ULONG *pcelt);
10806     COM_METHOD Next(ULONG celt,
10807                     ICorPublishProcess *objects[],
10808                     ULONG *pceltFetched);
10809
10810 private:
10811     CorpubProcess       *m_pFirst;
10812     CorpubProcess       *m_pCurrent;
10813
10814 };
10815
10816 class CorpubAppDomainEnum : public CordbCommonBase, public ICorPublishAppDomainEnum
10817 {
10818 public:
10819     CorpubAppDomainEnum(CorpubAppDomain *pFirst);
10820     virtual ~CorpubAppDomainEnum();
10821
10822
10823 #ifdef _DEBUG
10824     virtual const char * DbgGetName() { return "CordbAppDomainEnum"; }
10825 #endif
10826
10827
10828     //-----------------------------------------------------------
10829     // IUnknown
10830     //-----------------------------------------------------------
10831
10832     ULONG STDMETHODCALLTYPE AddRef()
10833     {
10834         return (BaseAddRef());
10835     }
10836     ULONG STDMETHODCALLTYPE Release()
10837     {
10838         return (BaseRelease());
10839     }
10840     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10841
10842     //-----------------------------------------------------------
10843     // ICorPublishAppDomainEnum
10844     //-----------------------------------------------------------
10845     COM_METHOD Skip(ULONG celt);
10846     COM_METHOD Reset();
10847     COM_METHOD Clone(ICorPublishEnum **ppEnum);
10848     COM_METHOD GetCount(ULONG *pcelt);
10849
10850     COM_METHOD Next(ULONG celt,
10851                     ICorPublishAppDomain *objects[],
10852                     ULONG *pceltFetched);
10853
10854 private:
10855     CorpubAppDomain     *m_pFirst;
10856     CorpubAppDomain     *m_pCurrent;
10857
10858 };
10859
10860 #endif // defined(FEATURE_DBG_PUBLISH)
10861
10862 class CordbHeapEnum : public CordbBase, public ICorDebugHeapEnum
10863 {
10864 public:
10865     CordbHeapEnum(CordbProcess *proc);
10866
10867 #ifdef _DEBUG
10868     virtual const char * DbgGetName() { return "CordbHeapEnum"; }
10869 #endif
10870
10871     //-----------------------------------------------------------
10872     // IUnknown
10873     //-----------------------------------------------------------
10874     ULONG STDMETHODCALLTYPE AddRef()
10875     {
10876         return (BaseAddRef());
10877     }
10878     ULONG STDMETHODCALLTYPE Release()
10879     {
10880         return (BaseRelease());
10881     }
10882     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10883
10884     COM_METHOD Skip(ULONG celt);
10885     COM_METHOD Reset();
10886     COM_METHOD Clone(ICorDebugEnum **ppEnum);
10887     COM_METHOD GetCount(ULONG *pcelt);
10888
10889     COM_METHOD Next(ULONG celt,
10890                     COR_HEAPOBJECT objects[],
10891                     ULONG *pceltFetched);
10892
10893     virtual void Neuter()
10894     {
10895         Clear();
10896         CordbBase::Neuter();
10897     }
10898 private:
10899     void Clear();
10900
10901 private:
10902     IDacDbiInterface::HeapWalkHandle mHeapHandle;
10903 };
10904
10905
10906 class CordbRefEnum : public CordbBase, public ICorDebugGCReferenceEnum
10907 {
10908 public:
10909     CordbRefEnum(CordbProcess *proc, BOOL walkWeakRefs);
10910     CordbRefEnum(CordbProcess *proc, CorGCReferenceType types);
10911
10912 #ifdef _DEBUG
10913     virtual const char * DbgGetName() { return "CordbHeapEnum"; }
10914 #endif
10915
10916     //-----------------------------------------------------------
10917     // IUnknown
10918     //-----------------------------------------------------------
10919     ULONG STDMETHODCALLTYPE AddRef()
10920     {
10921         return (BaseAddRef());
10922     }
10923     ULONG STDMETHODCALLTYPE Release()
10924     {
10925         return (BaseRelease());
10926     }
10927     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10928
10929     COM_METHOD Skip(ULONG celt);
10930     COM_METHOD Reset();
10931     COM_METHOD Clone(ICorDebugEnum **ppEnum);
10932     COM_METHOD GetCount(ULONG *pcelt);
10933
10934     COM_METHOD Next(ULONG celt,
10935                     COR_GC_REFERENCE refs[],
10936                     ULONG *pceltFetched);
10937
10938     virtual void Neuter();
10939     
10940 private:
10941     RefWalkHandle mRefHandle;
10942     BOOL mEnumStacksFQ;
10943     UINT32 mHandleMask;
10944 };
10945
10946 // Since the hash table of modules is per app domain (and
10947 // threads is per process) (for fast lookup from the appdomain/process),
10948 // we need this wrapper
10949 // here which allows us to iterate through an assembly's
10950 // modules.  Is basically filters out modules/threads that aren't
10951 // in the assembly/appdomain. This slow & awkward for assemblies, but fast
10952 // for the common case - appdomain lookup.
10953 class CordbEnumFilter : public CordbBase,
10954                         public ICorDebugThreadEnum,
10955                         public ICorDebugModuleEnum
10956 {
10957 public:
10958     CordbEnumFilter(CordbBase * pOwnerObj, NeuterList * pOwnerList);
10959     CordbEnumFilter(CordbEnumFilter*src);
10960     virtual ~CordbEnumFilter();
10961
10962     virtual void Neuter();
10963
10964
10965 #ifdef _DEBUG
10966     virtual const char * DbgGetName() { return "CordbEnumFilter"; }
10967 #endif
10968
10969
10970     //-----------------------------------------------------------
10971     // IUnknown
10972     //-----------------------------------------------------------
10973
10974     ULONG STDMETHODCALLTYPE AddRef()
10975     {
10976         return (BaseAddRef());
10977     }
10978     ULONG STDMETHODCALLTYPE Release()
10979     {
10980         return (BaseRelease());
10981     }
10982     COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
10983
10984     //-----------------------------------------------------------
10985     // Common methods
10986     //-----------------------------------------------------------
10987     COM_METHOD Skip(ULONG celt);
10988     COM_METHOD Reset();
10989     COM_METHOD Clone(ICorDebugEnum **ppEnum);
10990     COM_METHOD GetCount(ULONG *pcelt);
10991     //-----------------------------------------------------------
10992     // ICorDebugModuleEnum
10993     //-----------------------------------------------------------
10994     COM_METHOD Next(ULONG celt,
10995                     ICorDebugModule *objects[],
10996                     ULONG *pceltFetched);
10997
10998     //-----------------------------------------------------------
10999     // ICorDebugThreadEnum
11000     //-----------------------------------------------------------
11001     COM_METHOD Next(ULONG celt,
11002                     ICorDebugThread *objects[],
11003                     ULONG *pceltFetched);
11004
11005     HRESULT Init (ICorDebugModuleEnum *pModEnum, CordbAssembly *pAssembly);
11006     HRESULT Init (ICorDebugThreadEnum *pThreadEnum, CordbAppDomain *pAppDomain);
11007
11008
11009 private:
11010     HRESULT NextWorker(ULONG celt, ICorDebugModule *objects[], ULONG *pceltFetched);
11011     HRESULT NextWorker(ULONG celt,ICorDebugThread *objects[], ULONG *pceltFetched);
11012
11013     // Owning object is our link to the CordbProcess* tree. Never null until we're neutered.
11014     // NeuterList is related to the owning object. Need to cache it so that we can pass it on
11015     // to our clones.
11016     CordbBase *     m_pOwnerObj; // provides us w/ a CordbProcess*
11017     NeuterList *    m_pOwnerNeuterList;
11018
11019
11020     EnumElement *m_pFirst;
11021     EnumElement *m_pCurrent;
11022     int         m_iCount;
11023 };
11024
11025 // Helpers to double-check the RS results against DAC.
11026 #if defined(_DEBUG)
11027 void CheckAgainstDAC(CordbFunction * pFunc, void * pIP, mdMethodDef mdExpected);
11028 #endif
11029
11030 HRESULT CopyOutString(const WCHAR * pInputString, ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_opt(cchName, *pcchName) WCHAR szName[]);
11031
11032
11033
11034 inline UINT AllocCookieCordbEval(CordbProcess *pProc, CordbEval* p)
11035 {
11036     _ASSERTE(pProc->GetProcessLock()->HasLock());
11037     return pProc->m_EvalTable.Add(p);
11038 }
11039 inline CordbEval * UnwrapCookieCordbEval(CordbProcess *pProc, UINT cookie)
11040 {
11041     _ASSERTE(pProc->GetProcessLock()->HasLock());
11042     return pProc->m_EvalTable.LookupAndRemove(cookie);
11043 }
11044
11045
11046 // We defined this at the top of the file - undef it now so that we don't pollute other files.
11047 #undef CRITICAL_SECTION
11048
11049
11050 #ifdef RSCONTRACTS
11051
11052 //-----------------------------------------------------------------------------
11053 // For debug builds, we maintain some thread-state to track debug bits
11054 // to help us do some more aggressive asserts.
11055 //-----------------------------------------------------------------------------
11056
11057 class PublicAPIHolder;
11058 class PublicReentrantAPIHolder;
11059 class PublicCallbackHolder;
11060 class PublicDebuggerErrorCallbackHolder;
11061
11062 class DbgRSThread
11063 {
11064 public:
11065     friend class PublicAPIHolder;
11066     friend class PublicReentrantAPIHolder;
11067     friend class PublicCallbackHolder;
11068     friend class PublicDebuggerErrorCallbackHolder;
11069     friend class PrivateShimCallbackHolder;
11070
11071     DbgRSThread();
11072
11073     // The TLS slot that we'll put this thread object in.
11074     static DWORD s_TlsSlot;
11075
11076     static LONG s_Total; // Total count of thread objects
11077
11078     // Get a thread object for the current thread via a TLS lookup.
11079     static DbgRSThread * GetThread();
11080
11081     // Call during DllMain to release this.
11082     static DbgRSThread * Create()
11083     {
11084         InterlockedIncrement(&s_Total);
11085
11086         DbgRSThread * p = new (nothrow) DbgRSThread();
11087         BOOL f = TlsSetValue(s_TlsSlot, p);
11088         _ASSERT(f);
11089         return p;
11090     }
11091
11092     void Destroy()
11093     {
11094         InterlockedDecrement(&s_Total);
11095
11096         BOOL f = TlsSetValue(s_TlsSlot, NULL);
11097         _ASSERT(f);
11098
11099         delete this;
11100     }
11101
11102     // Return true if this thread is inside the RS.
11103     bool IsInRS() { return m_cInsideRS > 0; }
11104
11105     // Locking API..
11106     // These will assert if the operation is unsafe.
11107     void NotifyTakeLock(RSLock * pLock);
11108     void NotifyReleaseLock(RSLock * pLock);
11109
11110     // Used to map other resources (like thread access) into the lock hierachy.
11111     // Note this only effects lock leveling checks and doesn't effect HoldsAnyLock().
11112     void TakeVirtualLock(RSLock::ERSLockLevel level);
11113     void ReleaseVirtualLock(RSLock::ERSLockLevel level);
11114
11115     // return true if this thread is holding any RS locks. Useful to check on Public API transition boundaries.
11116     bool HoldsAnyDbgApiLocks() { return m_cTotalDbgApiLocks > 0; }
11117
11118     enum EThreadType
11119     {
11120         cOther,
11121         cW32ET
11122     };
11123     void SetThreadType(EThreadType e) { m_eThreadType = e; }
11124
11125     bool IsWin32EventThread() { return m_eThreadType == cW32ET; }
11126
11127     void SetUnrecoverableCallback(bool fIsUnrecoverableErrorCallback)
11128     {
11129         // Not reentrant.
11130         _ASSERTE(m_fIsUnrecoverableErrorCallback != fIsUnrecoverableErrorCallback);
11131
11132         m_fIsUnrecoverableErrorCallback = fIsUnrecoverableErrorCallback;
11133     }
11134
11135     inline void AssertThreadIsLockFree()
11136     {
11137         // If we're in an unrecoverable callback, we may hold locks.
11138         _ASSERTE(m_fIsUnrecoverableErrorCallback
11139             || !HoldsAnyDbgApiLocks() ||
11140             !"Thread should not have locks on public/internal transition");
11141     }
11142
11143 protected:
11144     EThreadType m_eThreadType;
11145
11146     // More debugging tidbits - tid that we're on, and a sanity checking cookie.
11147     DWORD m_tid;
11148     DWORD m_Cookie;
11149
11150     enum ECookie
11151     {
11152         COOKIE_VALUE = 0x12345678
11153     };
11154
11155
11156     // This tells us if the thread is currently in the scope of a PublicAPIHolder.
11157     int m_cInsideRS;
11158
11159     // This tells us if a thread is currently being dispatched via a callback.
11160     bool m_fIsInCallback;
11161
11162     // We explicitly track if this thread is in an unrecoverable error callback
11163     // b/c that will weaken some other asserts.
11164     // It would be nice to clean up the unrecoverable error callback and have it
11165     // behave like all the other callbacks. Then we can remove this.
11166     bool m_fIsUnrecoverableErrorCallback;
11167
11168     // Locking context. Used to tell what levels of locks we hold so we can determine if a lock is safe to take.
11169     int m_cLocks[RSLock::LL_MAX];
11170     int m_cTotalDbgApiLocks;
11171 };
11172
11173 //-----------------------------------------------------------------------------
11174 // Mark when we enter / exit public APIs
11175 //-----------------------------------------------------------------------------
11176
11177 // Holder for Non-reentrant Public API (this is the vast majority)
11178 class PublicAPIHolder
11179 {
11180 public:
11181     PublicAPIHolder()
11182     {
11183         // on entry
11184         DbgRSThread * pThread = DbgRSThread::GetThread();
11185         pThread->m_cInsideRS++;
11186         _ASSERTE(pThread->m_cInsideRS == 1 || !"Non-reentrant API being called re-entrantly");
11187
11188         // Should never be in public w/ these locks
11189         pThread->AssertThreadIsLockFree();
11190     }
11191     ~PublicAPIHolder() {
11192         // On exit.
11193         DbgRSThread * pThread = DbgRSThread::GetThread();
11194         pThread->m_cInsideRS--;
11195         _ASSERTE(!pThread->IsInRS());
11196
11197         // Should never be in public w/ these locks. If we assert here,
11198         // then we're leaking locks.
11199         pThread->AssertThreadIsLockFree();
11200     }
11201 };
11202
11203 // Holder for reentrant public API
11204 class PublicReentrantAPIHolder
11205 {
11206 public:
11207     PublicReentrantAPIHolder()
11208     {
11209         // on entry
11210         DbgRSThread * pThread = DbgRSThread::GetThread();
11211         pThread->m_cInsideRS++;
11212
11213         // Cache count now so that we can calidate it in the dtor.
11214         m_oldCount = pThread->m_cInsideRS;
11215         // Since a we may have been called from within the RS, we may hold locks
11216     }
11217     ~PublicReentrantAPIHolder()
11218     {
11219
11220         // On exit.
11221         DbgRSThread * pThread = DbgRSThread::GetThread();
11222
11223         // Ensure that our children were balanced
11224         _ASSERTE(pThread->m_cInsideRS == m_oldCount);
11225
11226         pThread->m_cInsideRS--;
11227         _ASSERTE(pThread->m_cInsideRS >= 0);
11228
11229         // Since a we may have been called from within the RS, we may hold locks
11230     }
11231 private:
11232     int  m_oldCount;
11233 };
11234
11235 // Special holder for DebuggerError callback. This adjusts InsideRS count w/o
11236 // verifying locks. This is very dangerous. We allow this b/c the Debugger Error callback can come at any time.
11237 class PublicDebuggerErrorCallbackHolder
11238 {
11239 public:
11240     PublicDebuggerErrorCallbackHolder()
11241     {
11242         // Exiting from RS; entering Cordbg via a callback
11243         DbgRSThread * pThread = DbgRSThread::GetThread();
11244
11245         // This callback is called from within the RS
11246         _ASSERTE(pThread->IsInRS());
11247
11248         // Debugger error callback may be called from deep within the RS (after many nestings).
11249         // So immediately jump to outside. We'll restore this in dtor.
11250         m_oldCount = pThread->m_cInsideRS;
11251         pThread->m_cInsideRS = 0;
11252
11253         _ASSERTE(!pThread->IsInRS());
11254
11255         // We may be leaking locks for the unrecoverable callback. We mark that so that
11256         // the asserts about locking can be relaxed.
11257         pThread->SetUnrecoverableCallback(true);
11258     }
11259
11260     ~PublicDebuggerErrorCallbackHolder()
11261     {
11262         // Re-entering RS from after a callback.
11263         DbgRSThread * pThread = DbgRSThread::GetThread();
11264
11265         pThread->SetUnrecoverableCallback(false);
11266         pThread->m_cInsideRS = m_oldCount;
11267
11268         // Our status of being "Inside the RS" is now restored.
11269         _ASSERTE(pThread->IsInRS());
11270     }
11271 private:
11272     int m_oldCount;
11273 };
11274
11275 //---------------------------------------------------------------------------------------
11276 //
11277 // This is the same as the PublicCallbackHolder, except that this class doesn't assert that we are not holding
11278 // any locks when we call out to the shim.  
11279 // 
11280 // Notes:
11281 //    @dbgtodo  shim, synchronization - We need to settle on one consistent relationshipo between the RS
11282 //    and the shim.  Then we can clean up the sychronization story.  Right now some code considers the shim
11283 //    to be outside of the RS, and so we cannot hold any locks when we call out to the shim.  However, there
11284 //    are cases where we must hold a lock when we call out to the shim.  For example, when we call out to the
11285 //    shim to do a V2-style stackwalk, we need to be holding the stop-go lock so that another thread can't
11286 //    come in and call Continue().  Finally, when we fix this, we should fix 
11287 //    PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM() as well.
11288 //
11289
11290 class PrivateShimCallbackHolder 
11291 {
11292 public:
11293     PrivateShimCallbackHolder()
11294     {
11295         // Exiting from RS; entering Cordbg via a callback
11296         DbgRSThread * pThread = DbgRSThread::GetThread();
11297
11298         // This callback is called from within the RS
11299         _ASSERTE(pThread->IsInRS());
11300
11301         // Debugger error callback may be called from deep within the RS (after many nestings).
11302         // So immediately jump to outside. We'll restore this in dtor.
11303         m_oldCount = pThread->m_cInsideRS;
11304         pThread->m_cInsideRS = 0;
11305
11306         _ASSERTE(!pThread->IsInRS());
11307     }
11308
11309     ~PrivateShimCallbackHolder()
11310     {
11311         // Re-entering RS from after a callback.
11312         DbgRSThread * pThread = DbgRSThread::GetThread();
11313
11314         pThread->m_cInsideRS = m_oldCount;
11315
11316         // Our status of being "Inside the RS" is now restored.
11317         _ASSERTE(pThread->IsInRS());
11318     }
11319 private:
11320     int m_oldCount;
11321 };
11322
11323 class InternalAPIHolder
11324 {
11325 public:
11326     InternalAPIHolder()
11327     {
11328         DbgRSThread * pThread = DbgRSThread::GetThread();
11329
11330         // Internal APIs should already be inside the RS.
11331         _ASSERTE(pThread->IsInRS() ||!"Internal API being called directly from outside (there should be a public API on the stack)");
11332     }
11333     void dummy() {}
11334 };
11335
11336 //---------------------------------------------------------------------------------------
11337 //
11338 // This is a simple holder to assert that the current thread is holding the process lock.  The purpose of 
11339 // having this holder is to enforce a lock ordering between the process lock in the RS and the DD lock in DAC.
11340 // If a thread needs to take the process lock, it must do so BEFORE taking the DD lock.  Otherwise we could have
11341 // a deadlock between the process lock and the DD lock.
11342 //
11343 // Normally we take the process lock before calling out to DAC, and every DAC API takes the DD lock on entry.
11344 // Moreover, normally DAC doesn't call back into the RS.  The exceptions we currently have are:
11345 // 1) enumeration callbacks (e.g. code:CordbProcess::AppDomainEnumerationCallback)
11346 // 2) code:IDacDbiInterface::IMetaDataLookup
11347 // 3) code:IDacDbiInterface::IAllocator
11348 // 4) code:IStringHolder
11349 //
11350 // Note that the last two are fine because they don't need to take the process lock.  The first two categories
11351 // need to take the process lock before calling into DAC to avoid potential deadlocks.
11352 //
11353
11354 class InternalDacCallbackHolder
11355 {
11356 public:
11357     InternalDacCallbackHolder(CordbProcess * pProcess)
11358     {
11359         _ASSERTE(pProcess->ThreadHoldsProcessLock());
11360     }
11361 };
11362
11363 // cotract that occurs at public builds.
11364 #define PUBLIC_CONTRACT \
11365     CONTRACTL { NOTHROW; } CONTRACTL_END;
11366
11367
11368 // Private hook for Shim to call into DBI.
11369 // Since Shim is considered outside DBI, we need to mark that we've re-entered.
11370 // Big difference is that we can throw across this boundary.
11371 // @dbgtodo  private shim hook - Eventually, these will all go away since the shim will be fully public.
11372 #define PUBLIC_API_ENTRY_FOR_SHIM(_pThis) \
11373     PublicAPIHolder __pah;
11374
11375
11376 #define PUBLIC_API_UNSAFE_ENTRY_FOR_SHIM(_pThis) \
11377     PublicDebuggerErrorCallbackHolder __pahCallback;
11378
11379 // @dbgtodo  shim, synchronization - Because of the problem mentioned in the comments for 
11380 // PrivateShimCallbackHolder, we need this macro so that we don't hit an assertion when we come back into
11381 // the RS from the shim.
11382 #define PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM(_pThis) \
11383     PublicReentrantAPIHolder __pah;
11384
11385 //-----------------------------------------------------------------------------
11386 // Declare whether an API is public or internal
11387 // Public APIs have the following:
11388 // - We may be called concurrently from multiple threads (ie, not thread safe)
11389 // - This thread does not hold any RS Locks while entering or leaving this function.
11390 // - May or May-not be reentrant.
11391 // Internal APIs:
11392 // - let us specifically mark that we're not a public API, and
11393 // - we're only being called through a public API.
11394 //-----------------------------------------------------------------------------
11395 #define PUBLIC_API_ENTRY(_pThis) \
11396     STRESS_LOG2(LF_CORDB, LL_INFO1000, "[Public API '%s', this=0x%p]\n", __FUNCTION__, _pThis); \
11397     PUBLIC_CONTRACT; \
11398     PublicAPIHolder __pah;
11399
11400 // Mark public APIs that are re-entrant.
11401 // Very few of our APIs should be re-entrant. Even for field access APIs (like GetXXX), the
11402 // public version is heavier (eg, checking the HRESULT) so we benefit from having a fast
11403 // internal version and calling that directly.
11404 #define PUBLIC_REENTRANT_API_ENTRY(_pThis) \
11405     STRESS_LOG2(LF_CORDB, LL_INFO1000, "[Public API (re) '%s', this=0x%p]\n", __FUNCTION__, _pThis); \
11406     PUBLIC_CONTRACT; \
11407     PublicReentrantAPIHolder __pah;
11408
11409
11410
11411 // Mark internal APIs.
11412 // All internal APIs are reentrant (duh)
11413 #define INTERNAL_API_ENTRY(_pThis) InternalAPIHolder __pah; __pah.dummy();
11414
11415 // Mark an internal API from ATT_REQUIRE_STOP / ATT_ALLOW_LIVE_DO_STOP_GO.
11416 // This can assert that we're safe to send IPC events (that we're stopped and hold the SG lock)
11417 // @dbgtodo  synchronization - in V2, this would assert that we were synced. 
11418 // In V3, our definition of Sync is in flux.  Need to resolve this with the synchronization feature crew.
11419 #define INTERNAL_SYNC_API_ENTRY(pProc)  \
11420     CordbProcess * __pProc = (pProc); \
11421     _ASSERTE(__pProc->GetStopGoLock()->HasLock() || !"Must have stop go lock for internal-sync-api"); \
11422     InternalAPIHolder __pah; __pah.dummy();
11423
11424
11425
11426 // Mark that a thread is owned by us. Thus the thread's "Inside RS" count > 0.
11427 #define INTERNAL_THREAD_ENTRY(_pThis) \
11428     STRESS_LOG1(LF_CORDB, LL_INFO1000, "[Internal thread started, this=0x%p]\n", _pThis); \
11429     PUBLIC_CONTRACT; \
11430     PublicAPIHolder __pah;
11431
11432 // @dbgtodo  unrecoverable error - This sould be deprecated once we deprecate UnrecoverableError.
11433 #define PUBLIC_CALLBACK_IN_THIS_SCOPE_DEBUGGERERROR(_pThis) \
11434     PublicDebuggerErrorCallbackHolder __pahCallback;
11435
11436 #define PRIVATE_SHIM_CALLBACK_IN_THIS_SCOPE0(_pThis) \
11437     PrivateShimCallbackHolder __pahCallback;
11438
11439 // Mark places where DAC may call back into DBI.  We need to assert that we are holding the process lock in
11440 // these places, since otherwise we could deadlock between the DD lock and the process lock.
11441 #define INTERNAL_DAC_CALLBACK(__pProcess) \
11442     InternalDacCallbackHolder __idch(__pProcess);
11443
11444
11445 // Helper to log debug events.
11446 inline void StressLogNativeDebugEvent(const DEBUG_EVENT * pDebugEvent, bool fOOB)
11447 {
11448     if ((pDebugEvent)->dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
11449     {
11450         STRESS_LOG4(LF_CORDB, LL_EVERYTHING, "[Dispatching Win32 code=1 (EXCEPTION_DEBUG_EVENT, tid=%x, oob=%d, code=0x%x, 1st=%d]\n",
11451             pDebugEvent->dwThreadId,
11452             fOOB,
11453             pDebugEvent->u.Exception.ExceptionRecord.ExceptionCode,
11454             pDebugEvent->u.Exception.dwFirstChance);
11455     }
11456     else
11457     {
11458         STRESS_LOG3(LF_CORDB, LL_EVERYTHING, "[Dispatching Win32 code=%d, tid=%x, oob=%d.]\n",
11459             pDebugEvent->dwDebugEventCode, pDebugEvent->dwThreadId, fOOB);
11460     }
11461
11462 }
11463
11464 #define PUBLIC_WIN32_CALLBACK_IN_THIS_SCOPE(_pThis, _pDebugEvent, _fOOB) \
11465     StressLogNativeDebugEvent(_pDebugEvent, _fOOB); \
11466     PublicCallbackHolder __pahCallback(DB_IPCE_INVALID_EVENT);
11467
11468 // Visisbility spec for dtors.
11469 // Currently, dtors are like public methods b/c they can be called from Release.
11470 // But they're also reentrant since they may be called from an internal-release.
11471 // @todo - we'd like to get all "useful" work out of the dtor; in which case we may
11472 // be able to change this to something more aggressive.
11473 #define DTOR_ENTRY(_pThis) PUBLIC_REENTRANT_API_ENTRY(_pThis)
11474
11475
11476 //-----------------------------------------------------------------------------
11477 // Typesafe bool for thread safety. This typesafety forces us to use
11478 // an specific reason for thread-safety, taken from a well-known list.
11479 // This is mostly concerned w/ being serialized.
11480 // Note that this assertion must be done on a per function basis and we
11481 // can't have any sort of 'ThreadSafetyReason CallerIsSafe()' b/c we can't
11482 // enforce that all of our callers are thread safe (only that our current caller is safe).
11483 //-----------------------------------------------------------------------------
11484 struct ThreadSafetyReason
11485 {
11486 public:
11487     ThreadSafetyReason(bool f) { fIsSafe = f; }
11488
11489     bool fIsSafe;
11490 };
11491
11492 // Different valid reasons that we may be threads safe.
11493 inline ThreadSafetyReason HoldsLock(RSLock * pLock)
11494 {
11495     _ASSERTE(pLock != NULL);
11496     return ThreadSafetyReason(pLock->HasLock());
11497 }
11498 inline ThreadSafetyReason OnW32ET(CordbProcess * pProc)
11499 {
11500     return ThreadSafetyReason(IsWin32EventThread(pProc));
11501 }
11502
11503 inline ThreadSafetyReason OnRCET(Cordb *pCordb)
11504 {
11505     return ThreadSafetyReason (IsRCEventThread(pCordb));
11506 }
11507
11508 // We use this when we assume that a function is thread-safe (b/c it's serialized).
11509 // The reason also lets us assert that our assumption is true.
11510 // By using a function, we enforce typesafety and thus require a valid reason
11511 // (as opposed to an arbitrary bool)
11512 inline void AssertThreadSafeHelper(ThreadSafetyReason r) {
11513     _ASSERTE(r.fIsSafe);
11514 }
11515
11516 //-----------------------------------------------------------------------------
11517 // Assert that the given scope is always called on a single thread b/c of
11518 // xReason. Common reasons may be b/c we hold a lock or we're always
11519 // called on a specific thread (Eg w32et).
11520 // The only valid reasons are of type ThreadSafetyReason (thus forcing us to
11521 // choose from a well-known list of valid reasons).
11522 //-----------------------------------------------------------------------------
11523 #define ASSERT_SINGLE_THREAD_ONLY(xReason) \
11524     AssertThreadSafeHelper(xReason);
11525
11526 #else
11527
11528 //-----------------------------------------------------------------------------
11529 // Retail versions just nop. See the debug implementation for these
11530 // for their semantics.
11531 //-----------------------------------------------------------------------------
11532
11533 #define PUBLIC_CONTRACT
11534 #define PUBLIC_API_ENTRY_FOR_SHIM(_pThis)
11535 #define PUBLIC_API_UNSAFE_ENTRY_FOR_SHIM(_pThis)
11536 #define PUBLIC_REENTRANT_API_ENTRY_FOR_SHIM(_pThis)
11537 #define PUBLIC_API_ENTRY(_pThis)
11538 #define PUBLIC_REENTRANT_API_ENTRY(_pThis)
11539 #define INTERNAL_API_ENTRY(_pThis)
11540 #define INTERNAL_SYNC_API_ENTRY(pProc)
11541 #define INTERNAL_THREAD_ENTRY(_pThis)
11542 #define PUBLIC_CALLBACK_IN_THIS_SCOPE_DEBUGGERERROR(_pThis)
11543 #define PRIVATE_SHIM_CALLBACK_IN_THIS_SCOPE0(_pThis)
11544 #define INTERNAL_DAC_CALLBACK(__pProcess)
11545 #define PUBLIC_WIN32_CALLBACK_IN_THIS_SCOPE(_pThis, _pDebugEvent, _fOOB)
11546 #define DTOR_ENTRY(_pThis)
11547
11548
11549 #define ASSERT_SINGLE_THREAD_ONLY(x)
11550
11551 #endif // #if RSCONTRACTS
11552
11553
11554 class PublicCallbackHolder
11555 {
11556 public:
11557     PublicCallbackHolder(RSLockHolder * pHolder, DebuggerIPCEventType type)        
11558     {
11559         m_pHolder = pHolder;
11560         _ASSERTE(!pHolder->IsNull()); // acquired
11561
11562         // Release the lock. We'll reacquire it at the dtor.
11563         m_pHolder->Release();
11564
11565         Init(type);
11566     }
11567
11568     PublicCallbackHolder(DebuggerIPCEventType type)
11569     {
11570         m_pHolder = NULL;
11571         Init(type);
11572     }
11573
11574     void Init(DebuggerIPCEventType type)
11575     {
11576         m_type = type;
11577
11578 #if defined(RSCONTRACTS)
11579         // Exiting from RS; entering Cordbg via a callback
11580         DbgRSThread * pThread = DbgRSThread::GetThread();
11581         
11582         // m_cInsideRS may be arbitrarily large if we're called from a PUBLIC_REENTRANT_API, 
11583         // so just remember the current count and blast it back to 0.
11584         m_oldCount = pThread->m_cInsideRS;
11585         pThread->m_cInsideRS = 0;
11586
11587         _ASSERTE(!pThread->IsInRS());
11588
11589         // Should never be in public w/ these locks. (Even if we're re-entrant.)
11590         pThread->AssertThreadIsLockFree();
11591 #endif // RSCONTRACTS
11592     }
11593
11594     ~PublicCallbackHolder()
11595     {
11596 #if defined(RSCONTRACTS)
11597         // Re-entering RS from after a callback.
11598         DbgRSThread * pThread = DbgRSThread::GetThread();
11599         _ASSERTE(!pThread->IsInRS());
11600         
11601         pThread->m_cInsideRS = m_oldCount;
11602
11603         // Should never be in public w/ these locks. (Even if we're re-entrant.)
11604         pThread->AssertThreadIsLockFree();
11605 #endif // RSCONTRACTS
11606
11607         // Reacquire the lock
11608         if (m_pHolder != NULL)
11609         {
11610             m_pHolder->Acquire();
11611         }
11612     }
11613 protected:
11614     int m_oldCount;
11615     DebuggerIPCEventType m_type;
11616     RSLockHolder * m_pHolder;
11617 };
11618
11619
11620 // Mark that a thread is calling out via a callback. This will adjust the "Inside RS" counter.
11621 #define PUBLIC_CALLBACK_IN_THIS_SCOPE(_pThis, pLockHolder, event) \
11622     STRESS_LOG1(LF_CORDB, LL_EVERYTHING, "[Dispatching '%s']\n", IPCENames::GetName((event)->type)); \
11623     PublicCallbackHolder __pahCallback(pLockHolder, (event)->type);
11624
11625 #define PUBLIC_CALLBACK_IN_THIS_SCOPE1(_pThis, pLockHolder, event, formatLiteralString, arg0) \
11626     STRESS_LOG2(LF_CORDB, LL_EVERYTHING, "[Dispatching '%s' " formatLiteralString "]\n", IPCENames::GetName((event)->type), arg0); \
11627     PublicCallbackHolder __pahCallback(pLockHolder, (event)->type);
11628
11629 #define PUBLIC_CALLBACK_IN_THIS_SCOPE2(_pThis, pLockHolder, event, formatLiteralString, arg0, arg1) \
11630     STRESS_LOG3(LF_CORDB, LL_EVERYTHING, "[Dispatching '%s' " formatLiteralString "]\n", IPCENames::GetName((event)->type), arg0, arg1); \
11631     PublicCallbackHolder __pahCallback(pLockHolder, (event)->type);
11632
11633 #define PUBLIC_CALLBACK_IN_THIS_SCOPE3(_pThis, pLockHolder, event, formatLiteralString, arg0, arg1, arg2) \
11634     STRESS_LOG4(LF_CORDB, LL_EVERYTHING, "[Dispatching '%s' " formatLiteralString "]\n", IPCENames::GetName((event)->type), arg0, arg1, arg2); \
11635     PublicCallbackHolder __pahCallback(pLockHolder, (event)->type);
11636
11637
11638 #define PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(_pThis) \
11639     PublicCallbackHolder __pahCallback(DB_IPCE_INVALID_EVENT);
11640
11641 #define PUBLIC_CALLBACK_IN_THIS_SCOPE0(_pThis, pLockHolder) \
11642     PublicCallbackHolder __pahCallback(pLockHolder, DB_IPCE_INVALID_EVENT);
11643
11644
11645 //-----------------------------------------------------------------------------
11646 // Helpers 
11647 inline void ValidateOrThrow(const void * p)
11648 {
11649     if (p == NULL)
11650     {
11651         ThrowHR(E_INVALIDARG);
11652     }
11653 }
11654
11655 // aligns argBase on platforms that require it else it's a no-op
11656 inline void AlignAddressForType(CordbType* pArgType, CORDB_ADDRESS& argBase)
11657 {
11658 #ifdef DBG_TARGET_ARM
11659 // TODO: review the following
11660 #ifdef FEATURE_64BIT_ALIGNMENT
11661     BOOL align = FALSE;
11662     HRESULT hr = pArgType->RequiresAlign8(&align);
11663     _ASSERTE(SUCCEEDED(hr));
11664
11665     if (align)
11666         argBase = ALIGN_ADDRESS(argBase, 8);
11667 #endif // FEATURE_64BIT_ALIGNMENT
11668 #endif // DBG_TARGET_ARM
11669 }
11670
11671 //-----------------------------------------------------------------------------
11672 // Macros to mark public ICorDebug functions
11673 // Usage:
11674 //
11675 //  HRESULT CordbXYZ:Function(...) 
11676 //  {
11677 //      HRESULT hr = S_OK;
11678 //      PUBLIC_API_BEGIN(this);
11679 //         // body, may throw
11680 //      PUBLIC_API_END(hr);
11681 //      return hr;
11682 //  }
11683 #define PUBLIC_API_BEGIN(__this) \
11684     CordbBase * __pThis = (__this); \
11685     PUBLIC_API_ENTRY(__pThis); \
11686     EX_TRY { \
11687        RSLockHolder __lockHolder(__pThis->GetProcess()->GetProcessLock()); \
11688        THROW_IF_NEUTERED(__pThis); \
11689
11690 // You should not use this in general. We're adding it as a temporary workaround for a 
11691 // particular scenario until we do the synchronization feature crew
11692 #define PUBLIC_API_NO_LOCK_BEGIN(__this) \
11693     CordbBase * __pThis = (__this); \
11694     PUBLIC_API_ENTRY(__pThis); \
11695     EX_TRY { \
11696        THROW_IF_NEUTERED(__pThis); \
11697
11698 // Some APIs (that invoke callbacks), need to toggle the lock.
11699 #define GET_PUBLIC_LOCK_HOLDER() (&__lockHolder)
11700
11701 #define PUBLIC_API_END(__hr) \
11702     } EX_CATCH_HRESULT(__hr); \
11703
11704 // @todo: clean up API constracts. Should we really be taking the Process lock for 
11705 // reentrant APIS?? 
11706 #define PUBLIC_REENTRANT_API_BEGIN(__this) \
11707     CordbBase * __pThis = (__this); \
11708     PUBLIC_REENTRANT_API_ENTRY(__pThis); \
11709     EX_TRY { \
11710        RSLockHolder __lockHolder(__pThis->GetProcess()->GetProcessLock()); \
11711        THROW_IF_NEUTERED(__pThis); \
11712
11713 #define PUBLIC_REENTRANT_API_END(__hr) \
11714     } EX_CATCH_HRESULT(__hr); \
11715
11716 // If an API needs to take the stop/go lock as well as the process lock, the
11717 // stop/go lock has to be taken first. This is an alternative to PUBLIC_REENTRANT_API_BEGIN
11718 // that allows this, since it doesn't take the process lock. It should be closed with 
11719 // PUBLIC_REENTRANT_API_END
11720 #define PUBLIC_REENTRANT_API_NO_LOCK_BEGIN(__this) \
11721     CordbBase * __pThis = (__this); \
11722     PUBLIC_REENTRANT_API_ENTRY(__pThis); \
11723     EX_TRY { \
11724        THROW_IF_NEUTERED(__pThis); \
11725
11726
11727 //-----------------------------------------------------------------------------
11728 // For debugging ease, cache some global values.
11729 // Include these in retail & free because that's where we need them the most!!
11730 // Optimized builds may not let us view locals & parameters. So Having these
11731 // cached as global values should let us inspect almost all of
11732 // the interesting parts of the RS even in a Retail build!
11733 //-----------------------------------------------------------------------------
11734 struct RSDebuggingInfo
11735 {
11736     // There should only be 1 global Cordb object. Store it here.
11737     Cordb * m_Cordb;
11738
11739     // We have lots of processes. Keep a pointer to the most recently touched
11740     // (subjective) process, as a hint about what our "current" process is.
11741     // If we're only debugging 1 process, this will be sufficient.
11742     CordbProcess * m_MRUprocess;
11743
11744     CordbRCEventThread * m_RCET;
11745 };
11746
11747 #include "rspriv.inl"
11748
11749 #endif // #if RSPRIV_H
11750
11751