a6d943fb2630e5f42944a6c4f449bc5bac8e36ad
[platform/upstream/coreclr.git] / src / debug / inc / dbgipcevents.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 /* ------------------------------------------------------------------------- *
5  * DbgIPCEvents.h -- header file for private Debugger data shared by various
6 // 
7
8  *                   debugger components.
9  * ------------------------------------------------------------------------- */
10
11 #ifndef _DbgIPCEvents_h_
12 #define _DbgIPCEvents_h_
13
14 #include <new.hpp>
15 #include <cor.h>
16 #include <cordebug.h>
17 #include <corjit.h> // for ICorDebugInfo::VarLocType & VarLoc
18 #include <specstrings.h>
19
20 #include "dbgtargetcontext.h"
21
22
23 // Get version numbers for IPCHeader stamp
24 #include "ndpversion.h"
25
26 #include "dbgappdomain.h"
27
28 #include "./common.h"
29
30 //-----------------------------------------------------------------------------
31 // V3 additions to IPC protocol between LS and RS.
32 //-----------------------------------------------------------------------------
33
34 // Special Exception code for LS to communicate with RS. 
35 // LS will raise this exception to communicate managed debug events to the RS.
36 // Exception codes can't use bit 0x10000000, that's reserved by OS.
37 #define CLRDBG_NOTIFICATION_EXCEPTION_CODE  ((DWORD) 0x04242420)
38
39 // This is exception argument 0 included in debugger notification events. 
40 // The debugger uses this as a sanity check.
41 // This could be very volatile data that changes between builds.
42 #define CLRDBG_EXCEPTION_DATA_CHECKSUM ((DWORD) 0x31415927)
43
44
45 // Reasons for hijack.
46 namespace EHijackReason
47 {
48     enum EHijackReason
49     {
50         kUnhandledException = 1,
51         kM2UHandoff = 2,
52         kFirstChanceSuspend = 3,
53         kGenericHijack = 4,
54         kMax
55     };
56     inline bool IsValid(EHijackReason value)
57     {
58         SUPPORTS_DAC;
59         return (value > 0) && (value < kMax);
60     }
61 }
62
63
64
65 #define     MAX_LOG_SWITCH_NAME_LEN     256
66
67 //-----------------------------------------------------------------------------
68 // Versioning note:
69 // This file describes the IPC communication protocol between the LS (mscorwks)
70 // and the RS (mscordbi). For Desktop builds, it is private and can change on a 
71 // daily basis. The version of the LS will always match the version of the RS 
72 // (but see the discussion of CoreCLR below). They are like a single conceptual 
73 // DLL split across 2 processes. 
74 // The only restriction is that it should be flavor agnostic - so don't change
75 // layout based off '#ifdef DEBUG'. This lets us drop a Debug flavor RS onto
76 // a retail installation w/o any further installation woes. That's very useful
77 // for debugging.
78 //-----------------------------------------------------------------------------
79
80
81 // We want this available for DbgInterface.h - put it here.
82 typedef enum
83 {
84     IPC_TARGET_OUTOFPROC,
85     IPC_TARGET_COUNT,
86 } IpcTarget;
87
88 //
89 // Names of the setup sync event and shared memory used for IPC between the Left Side and the Right Side. NOTE: these
90 // names must include a %d for the process id. The process id used is the process id of the debuggee.
91 //
92
93 #define CorDBIPCSetupSyncEventName W("CorDBIPCSetupSyncEvent_%d")
94
95 //
96 // This define controls whether we always pass first chance exceptions to the in-process first chance hijack filter
97 // during interop debugging or if we try to short-circuit and make the decision out-of-process as much as possible.
98 //
99 #define CorDB_Short_Circuit_First_Chance_Ownership 1
100
101 //
102 // Defines for current version numbers for the left and right sides
103 //
104 #define CorDB_LeftSideProtocolCurrent           2
105 #define CorDB_LeftSideProtocolMinSupported      2
106 #define CorDB_RightSideProtocolCurrent          2
107 #define CorDB_RightSideProtocolMinSupported     2
108
109 //
110 // The remaining data structures in this file can be shared between two processes and for network transport
111 // based debugging this can mean two different platforms as well.  The two platforms that can share these 
112 // data structures must have identical layouts for them (each field must lie at the same offset and have the 
113 // same length). The MSLAYOUT macro should be applied to each structure to avoid any compiler packing differences.
114 //
115
116 //
117 // DebuggerIPCRuntimeOffsets contains addresses and offsets of important global variables, functions, and fields in
118 // Runtime objects. This is populated during Left Side initialization and is read by the Right Side. This struct is
119 // mostly to facilitate unmanaged debugging support, but it may have some small uses for managed debugging.
120 //
121 struct MSLAYOUT DebuggerIPCRuntimeOffsets
122 {
123 #ifdef FEATURE_INTEROP_DEBUGGING
124     void   *m_genericHijackFuncAddr;
125     void   *m_signalHijackStartedBPAddr;
126     void   *m_excepForRuntimeHandoffStartBPAddr;
127     void   *m_excepForRuntimeHandoffCompleteBPAddr;
128     void   *m_signalHijackCompleteBPAddr;
129     void   *m_excepNotForRuntimeBPAddr;
130     void   *m_notifyRSOfSyncCompleteBPAddr;
131     void   *m_raiseExceptionAddr;                       // The address of kernel32!RaiseException in the debuggee
132     DWORD   m_debuggerWordTLSIndex;                     // The TLS slot for the debugger word used in the debugger hijack functions
133 #endif // FEATURE_INTEROP_DEBUGGING
134     SIZE_T  m_TLSIndex;                                 // The TLS index the CLR is using to hold Thread objects
135     SIZE_T  m_TLSIsSpecialIndex;                        // The index into the Predef block of the the "IsSpecial" status for a thread.
136     SIZE_T  m_TLSCantStopIndex;                         // The index into the Predef block of the the Can't-Stop count.
137     SIZE_T  m_EEThreadStateOffset;                      // Offset of m_state in a Thread
138     SIZE_T  m_EEThreadStateNCOffset;                    // Offset of m_stateNC in a Thread
139     SIZE_T  m_EEThreadPGCDisabledOffset;                // Offset of the bit for whether PGC is disabled or not in a Thread
140     DWORD   m_EEThreadPGCDisabledValue;                 // Value at m_EEThreadPGCDisabledOffset that equals "PGC disabled".
141     SIZE_T  m_EEThreadFrameOffset;                      // Offset of the Frame ptr in a Thread
142     SIZE_T  m_EEThreadMaxNeededSize;                    // Max memory to read to get what we need out of a Thread object
143     DWORD   m_EEThreadSteppingStateMask;                // Mask for Thread::TSNC_DebuggerIsStepping
144     DWORD   m_EEMaxFrameValue;                          // The max Frame value
145     SIZE_T  m_EEThreadDebuggerFilterContextOffset;      // Offset of debugger's filter context within a Thread Object.
146     SIZE_T  m_EEThreadCantStopOffset;                   // Offset of the can't stop count in a Thread
147     SIZE_T  m_EEFrameNextOffset;                        // Offset of the next ptr in a Frame
148     DWORD   m_EEIsManagedExceptionStateMask;            // Mask for Thread::TSNC_DebuggerIsManagedException
149     void   *m_pPatches;                                 // Addr of patch table
150     BOOL   *m_pPatchTableValid;                         // Addr of g_patchTableValid
151     SIZE_T  m_offRgData;                                // Offset of m_pcEntries
152     SIZE_T  m_offCData;                                 // Offset of count of m_pcEntries
153     SIZE_T  m_cbPatch;                                  // Size per patch entry
154     SIZE_T  m_offAddr;                                  // Offset within patch of target addr
155     SIZE_T  m_offOpcode;                                // Offset within patch of target opcode
156     SIZE_T  m_cbOpcode;                                 // Max size of opcode
157     SIZE_T  m_offTraceType;                             // Offset of the trace.type within a patch
158     DWORD   m_traceTypeUnmanaged;                       // TRACE_UNMANAGED
159
160     DebuggerIPCRuntimeOffsets()
161     {
162         ZeroMemory(this, sizeof(DebuggerIPCRuntimeOffsets));
163     }
164 };
165
166 //
167 // The size of the send and receive IPC buffers.
168 // These must be big enough to fit a DebuggerIPCEvent. Also, the bigger they are, the fewer events
169 // it takes to send variable length stuff like the stack trace.
170 // But for perf reasons, they need to be small enough to not just push us over a page boundary in an IPC block.
171 // Unfortunately, there's a lot of other goo in the IPC block, so we can't use some clean formula. So we
172 // have to resort to just tuning things.
173 //
174
175 // When using a network transport rather than shared memory buffers CorDBIPC_BUFFER_SIZE is the upper bound
176 // for a single DebuggerIPCEvent structure. This now relates to the maximal size of a network message and is
177 // orthogonal to the host's page size. Because of this we defer definition of CorDBIPC_BUFFER_SIZE until we've
178 // declared DebuggerIPCEvent at the end of this header (and we can do so because in the transport case there
179 // aren't any embedded buffers in the DebuggerIPCControlBlock).
180
181 #if defined(DBG_TARGET_X86) || defined(DBG_TARGET_ARM)
182 #ifdef _WIN64
183 #define CorDBIPC_BUFFER_SIZE 2104
184 #else
185 #define CorDBIPC_BUFFER_SIZE 2092
186 #endif
187 #else  // !_TARGET_X86_ && !_TARGET_ARM_
188 // This is the size of a DebuggerIPCEvent.  You will hit an assert in Cordb::Initialize() (di\rsmain.cpp)
189 // if this is not defined correctly.  AMD64 actually has a page size of 0x1000, not 0x2000.
190 #define CorDBIPC_BUFFER_SIZE 4016 // (4016 + 6) * 2 + 148 = 8192 (two (DebuggerIPCEvent + alignment padding) + other fields = page size)
191 #endif // DBG_TARGET_X86 || DBG_TARGET_ARM
192
193 //
194 // DebuggerIPCControlBlock describes the layout of the shared memory shared between the Left Side and the Right
195 // Side. This includes error information, handles for the IPC channel, and space for the send/receive buffers.
196 //
197 struct MSLAYOUT DebuggerIPCControlBlock
198 {
199     // Version data should be first in the control block to ensure that we can read it even if the control block
200     // changes.
201     SIZE_T                     m_DCBSize;           // note this field is used as a semaphore to indicate the DCB is initialized
202     ULONG                      m_verMajor;          // CLR build number for the Left Side.
203     ULONG                      m_verMinor;          // CLR build number for the Left Side.
204
205     // This next stuff fits in a  DWORD.
206     bool                       m_checkedBuild;      // CLR build type for the Left Side.
207     // using the first padding byte to indicate if hosted in fiber mode.
208     // We actually just need one bit. So if needed, can turn this to a bit.
209     // BYTE padding1;
210     bool                       m_bHostingInFiber;
211     BYTE padding2;
212     BYTE padding3;
213
214     ULONG                      m_leftSideProtocolCurrent;       // Current protocol version for the Left Side.
215     ULONG                      m_leftSideProtocolMinSupported;  // Minimum protocol the Left Side can support.
216
217     ULONG                      m_rightSideProtocolCurrent;      // Current protocol version for the Right Side.
218     ULONG                      m_rightSideProtocolMinSupported; // Minimum protocol the Right Side requires.
219
220     HRESULT                    m_errorHR;
221     unsigned int               m_errorCode;
222
223 #if defined(DBG_TARGET_WIN64)
224     // 64-bit needs this padding to make the handles after this aligned.
225     // But x86 can't have this padding b/c it breaks binary compatibility between v1.1 and v2.0.
226     ULONG padding4;
227 #endif // DBG_TARGET_WIN64
228
229
230     RemoteHANDLE               m_rightSideEventAvailable;
231     RemoteHANDLE               m_rightSideEventRead;
232
233     // @dbgtodo  inspection - this is where LSEA and LSER used to be. We need to the padding to maintain binary compatibility.
234     // Eventually, we expect to remove this whole block.
235     RemoteHANDLE               m_paddingObsoleteLSEA;
236     RemoteHANDLE               m_paddingObsoleteLSER;
237
238     RemoteHANDLE               m_rightSideProcessHandle;
239
240     //.............................................................................
241     // Everything above this point must have the exact same binary layout as v1.1.
242     // See protocol details below.
243     //.............................................................................
244
245     RemoteHANDLE               m_leftSideUnmanagedWaitEvent;
246     
247
248
249     // This is set immediately when the helper thread is created.
250     // This will be set even if there's a temporary helper thread or if the real helper
251     // thread is not yet pumping (eg, blocked on a loader lock).
252     DWORD                      m_realHelperThreadId;
253
254     // This is only published once the helper thread starts running in its main loop.
255     // Thus we can use this field to see if the real helper thread is actually pumping.
256     DWORD                      m_helperThreadId;
257
258     // This is non-zero if the LS has a temporary helper thread.
259     DWORD                      m_temporaryHelperThreadId;
260
261     // ID of the Helper's canary thread.
262     DWORD                      m_CanaryThreadId;
263
264     DebuggerIPCRuntimeOffsets *m_pRuntimeOffsets;
265     void                      *m_helperThreadStartAddr;
266     void                      *m_helperRemoteStartAddr;
267     DWORD                     *m_specialThreadList;
268
269     BYTE                       m_receiveBuffer[CorDBIPC_BUFFER_SIZE];
270     BYTE                       m_sendBuffer[CorDBIPC_BUFFER_SIZE];
271
272     DWORD                      m_specialThreadListLength;
273     bool                       m_shutdownBegun;
274     bool                       m_rightSideIsWin32Debugger;  // RS status
275     bool                       m_specialThreadListDirty;
276
277     bool                       m_rightSideShouldCreateHelperThread;
278
279     // NOTE The Init method works since there are no virtual functions - don't add any virtual functions without
280     // changing this!
281     // Only initialized by the LS, opened by the RS.
282     HRESULT Init(
283                  HANDLE rsea, 
284                  HANDLE rser, 
285                  HANDLE lsea, 
286                  HANDLE lser,
287                  HANDLE lsuwe
288                 );
289
290 };
291
292 #if defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
293
294 // We need an alternate definition for the control block if using the transport, because the control block has to be sent over the transport
295 // In particular we can't nest the send/receive buffers inside of it and we don't use any of the remote handles
296
297 struct MSLAYOUT DebuggerIPCControlBlockTransport
298 {
299     // Version data should be first in the control block to ensure that we can read it even if the control block
300     // changes.
301     SIZE_T                     m_DCBSize;           // note this field is used as a semaphore to indicate the DCB is initialized
302     ULONG                      m_verMajor;          // CLR build number for the Left Side.
303     ULONG                      m_verMinor;          // CLR build number for the Left Side.
304
305     // This next stuff fits in a  DWORD.
306     bool                       m_checkedBuild;      // CLR build type for the Left Side.
307     // using the first padding byte to indicate if hosted in fiber mode.
308     // We actually just need one bit. So if needed, can turn this to a bit.
309     // BYTE padding1;
310     bool                       m_bHostingInFiber;
311     BYTE padding2;
312     BYTE padding3;
313
314     ULONG                      m_leftSideProtocolCurrent;       // Current protocol version for the Left Side.
315     ULONG                      m_leftSideProtocolMinSupported;  // Minimum protocol the Left Side can support.
316
317     ULONG                      m_rightSideProtocolCurrent;      // Current protocol version for the Right Side.
318     ULONG                      m_rightSideProtocolMinSupported; // Minimum protocol the Right Side requires.
319
320     HRESULT                    m_errorHR;
321     unsigned int               m_errorCode;
322
323 #if defined(DBG_TARGET_WIN64)
324     // 64-bit needs this padding to make the handles after this aligned.
325     // But x86 can't have this padding b/c it breaks binary compatibility between v1.1 and v2.0.
326     ULONG padding4;
327 #endif // DBG_TARGET_WIN64
328
329     // This is set immediately when the helper thread is created.
330     // This will be set even if there's a temporary helper thread or if the real helper
331     // thread is not yet pumping (eg, blocked on a loader lock).
332     DWORD                      m_realHelperThreadId;
333
334     // This is only published once the helper thread starts running in its main loop.
335     // Thus we can use this field to see if the real helper thread is actually pumping.
336     DWORD                      m_helperThreadId;
337
338     // This is non-zero if the LS has a temporary helper thread.
339     DWORD                      m_temporaryHelperThreadId;
340
341     // ID of the Helper's canary thread.
342     DWORD                      m_CanaryThreadId;
343
344     DebuggerIPCRuntimeOffsets *m_pRuntimeOffsets;
345     void                      *m_helperThreadStartAddr;
346     void                      *m_helperRemoteStartAddr;
347     DWORD                     *m_specialThreadList;
348
349     DWORD                      m_specialThreadListLength;
350     bool                       m_shutdownBegun;
351     bool                       m_rightSideIsWin32Debugger;  // RS status
352     bool                       m_specialThreadListDirty;
353
354     bool                       m_rightSideShouldCreateHelperThread;
355
356     // NOTE The Init method works since there are no virtual functions - don't add any virtual functions without
357     // changing this!
358     // Only initialized by the LS, opened by the RS.
359     HRESULT Init();
360
361 };
362
363 #endif // defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
364
365 #if defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
366 #include "dbgtransportsession.h"
367 #endif // defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
368
369 #if defined(DBG_TARGET_X86) && !defined(FEATURE_CORESYSTEM)
370 // We have an versioning requirement.
371 // Certain portions of the v1.0 and v1.1 IPC block are shared. This is b/c a v1.1 debugger needs to be able
372 // to look at a v2.0 app enough to recognize the version mismatch.
373 // This check is only necessary for platforms that ran on v1.1 (Win32-x86)
374
375 // Just to catch any potential illegal change in the IPC block, we assert the offsets against the offsets from v1.1.
376 // The constants here are pulled from v1.1.
377 // The RS will look at these versioning fields, so they absolutely must line up.
378 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_leftSideProtocolCurrent) == 0x10);
379 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_leftSideProtocolMinSupported) == 0x14);
380 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProtocolCurrent) == 0x18);
381 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProtocolMinSupported) == 0x1c);
382
383 // Unfortunately, on detecting such failure, v1.1 will also null out LSEA, LSER and RSPH.
384 // If these get adjusted, a version-mismatch attach  will effectively null out random fields.
385 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_paddingObsoleteLSEA) == 0x30);
386 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_paddingObsoleteLSER) == 0x34);
387 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProcessHandle) == 0x38);
388
389
390
391 #endif
392
393 #define INITIAL_APP_DOMAIN_INFO_LIST_SIZE   16
394
395
396 //-----------------------------------------------------------------------------
397 // Provide some Type-safety in the IPC block when we pass remote pointers around.
398 //-----------------------------------------------------------------------------
399
400
401 //-----------------------------------------------------------------------------
402 // This is the same in both the LS & RS.
403 // Definitions on the LS & RS should be binary compatible. So all storage is
404 // declared in GeneralLsPointer, and then the Ls & RS each have their own
405 // derived accessors.
406 //-----------------------------------------------------------------------------
407 class MSLAYOUT GeneralLsPointer
408 {
409 protected:
410     friend ULONG_PTR LsPtrToCookie(GeneralLsPointer p);
411     void * m_ptr;
412
413 public:
414     bool IsNull() { return m_ptr == NULL; }
415 };
416
417 class MSLAYOUT GeneralRsPointer
418 {
419 protected:
420     UINT m_data;
421
422 public:
423     bool IsNull() { return m_data == 0; }
424 };
425
426 // In some cases, we need to get a uuid from a pointer (ie, in a hash)
427 inline ULONG_PTR LsPtrToCookie(GeneralLsPointer p) {
428     return (ULONG_PTR) p.m_ptr;
429 }
430 #define VmPtrToCookie(vm) LsPtrToCookie((vm).ToLsPtr())
431
432
433 #ifdef RIGHT_SIDE_COMPILE
434 //-----------------------------------------------------------------------------
435 // Infrasturcture for RS Definitions
436 //-----------------------------------------------------------------------------
437
438 // On the RS, we don't have the LS classes defined, so we can't templatize that
439 // in terms of <class T>, but we still want things to be unique.
440 // So we create an empty enum for each LS type and then templatize it in terms
441 // of the enum.
442 template <typename T>
443 class MSLAYOUT LsPointer : public GeneralLsPointer
444 {
445 public:
446     void Set(void * p)
447     {
448         m_ptr = p;
449     }
450     void * UnsafeGet()
451     {
452         return m_ptr;
453     }
454
455     static LsPointer<T> NullPtr()
456     {
457         return MakePtr(NULL);
458     }
459
460     static LsPointer<T> MakePtr(T* p)
461     {
462 #ifdef _PREFAST_
463 #pragma warning(push)
464 #pragma warning(disable:6001) // PREfast warning: Using uninitialize memory 't'
465 #endif // _PREFAST_
466
467         LsPointer<T> t;
468         t.Set(p);
469         return t;
470
471 #ifdef _PREFAST_
472 #pragma warning(pop)
473 #endif // _PREFAST_
474     }
475
476     bool operator!= (void * p) { return m_ptr != p; }
477     bool operator== (void * p) { return m_ptr == p; }
478     bool operator==(LsPointer<T> p) { return p.m_ptr == this->m_ptr; }
479
480     // We should never UnWrap() them in the RS, so we don't define that here.
481 };
482
483 class CordbProcess;
484 template <class T> UINT AllocCookie(CordbProcess * pProc, T * p);
485 template <class T> T * UnwrapCookie(CordbProcess * pProc, UINT cookie);
486
487 UINT AllocCookieCordbEval(CordbProcess * pProc, class CordbEval * p);
488 class CordbEval * UnwrapCookieCordbEval(CordbProcess * pProc, UINT cookie);
489
490 template <class CordbEval> UINT AllocCookie(CordbProcess * pProc, CordbEval * p)
491 {
492     return AllocCookieCordbEval(pProc, p);
493 }
494 template <class CordbEval> CordbEval * UnwrapCookie(CordbProcess * pProc, UINT cookie)
495 {
496     return UnwrapCookieCordbEval(pProc, cookie);
497 }
498
499
500
501 // This is how the RS sees the pointers in the IPC block.
502 template<class T>
503 class MSLAYOUT RsPointer : public GeneralRsPointer
504 {
505 public:
506     // Since we're being used inside a union, we can't have a ctor.
507
508     static RsPointer<T> NullPtr()
509     {
510         RsPointer<T> t;
511         t.m_data = 0;
512         return t;        
513     }
514
515     bool AllocHandle(CordbProcess *pProc, T* p)
516     {    
517         // This will force validation.
518         m_data = AllocCookie<T>(pProc, p);
519         return (m_data != 0);       
520     }
521
522     bool operator==(RsPointer<T> p) { return p.m_data == this->m_data; }
523
524     T* UnWrapAndRemove(CordbProcess *pProc)
525     {
526         return UnwrapCookie<T>(pProc, m_data);
527     }
528     
529 protected:
530 };
531
532 // Forward declare a class so that each type of LS pointer can have
533 // its own type.  We use the real class name to be compatible with VMPTRs.
534 #define DEFINE_LSPTR_TYPE(ls_type, ptr_name) \
535     ls_type; \
536     typedef LsPointer<ls_type> ptr_name;
537
538
539 #define DEFINE_RSPTR_TYPE(rs_type, ptr_name) \
540     class rs_type; \
541     typedef RsPointer<rs_type> ptr_name;
542
543 #else // !RIGHT_SIDE_COMPILE
544 //-----------------------------------------------------------------------------
545 // Infrastructure for LS Definitions
546 //-----------------------------------------------------------------------------
547
548 // This is how the LS sees the pointers in the IPC block.
549 template<typename T>
550 class MSLAYOUT LsPointer : public GeneralLsPointer
551 {
552 public:
553     // Since we're being used inside a union, we can't have a ctor.
554     //LsPointer() { }
555
556     static LsPointer<T> NullPtr()
557     {
558         return MakePtr(NULL);
559     }
560
561     static LsPointer<T> MakePtr(T * p)
562     {
563 #ifdef _PREFAST_
564 #pragma warning(push)
565 #pragma warning(disable:6001) // PREfast warning: Using uninitialize memory 't'
566 #endif // _PREFAST_
567
568         LsPointer<T> t;
569         t.Set(p);
570         return t;
571
572 #ifdef _PREFAST_
573 #pragma warning(pop)
574 #endif // _PREFAST_
575     }
576
577     bool operator!= (void * p) { return m_ptr != p; }
578     bool operator== (void * p) { return m_ptr == p; }
579     bool operator==(LsPointer<T> p) { return p.m_ptr == this->m_ptr; }
580
581     // @todo - we want to be able to swap out Set + Unwrap functions
582     void Set(T * p)
583     {
584         SUPPORTS_DAC;
585         // We could validate the pointer here.
586         m_ptr = p;
587     }
588
589     T * UnWrap()
590     {
591         // If we wanted to validate the pointer, here's our chance.
592         return static_cast<T*>(m_ptr);        
593     }
594 };
595
596 template <class n>
597 class MSLAYOUT RsPointer : public GeneralRsPointer
598 {
599 public:
600     static RsPointer<n> NullPtr()
601     {
602         RsPointer<n> t;
603         t.m_data = 0;
604         return t;
605     }
606
607     bool operator==(RsPointer<n> p) { return p.m_data == this->m_data; }
608
609     // We should never UnWrap() them in the LS, so we don't define that here.
610 };
611
612 #define DEFINE_LSPTR_TYPE(ls_type, ptr_name) \
613     ls_type; \
614     typedef LsPointer<ls_type> ptr_name;
615
616 #define DEFINE_RSPTR_TYPE(rs_type, ptr_name) \
617     enum __RS__##rs_type { };  \
618     typedef RsPointer<__RS__##rs_type> ptr_name;
619
620 #endif // !RIGHT_SIDE_COMPILE
621
622 // We must be binary compatible w/ a pointer.
623 static_assert_no_msg(sizeof(LsPointer<void>) == sizeof(GeneralLsPointer));
624
625 static_assert_no_msg(sizeof(void*) == sizeof(GeneralLsPointer));
626
627
628
629 //-----------------------------------------------------------------------------
630 // Definitions for Left-Side ptrs.
631 // NOTE: Use VMPTR instead of LSPTR. Don't add new LSPTR types.
632 // 
633 //-----------------------------------------------------------------------------
634
635
636
637 DEFINE_LSPTR_TYPE(class Assembly,  LSPTR_ASSEMBLY);
638 DEFINE_LSPTR_TYPE(class DebuggerJitInfo, LSPTR_DJI);
639 DEFINE_LSPTR_TYPE(class DebuggerMethodInfo, LSPTR_DMI);
640 DEFINE_LSPTR_TYPE(class MethodDesc,         LSPTR_METHODDESC);
641 DEFINE_LSPTR_TYPE(class DebuggerBreakpoint, LSPTR_BREAKPOINT);
642 DEFINE_LSPTR_TYPE(class DebuggerEval,       LSPTR_DEBUGGEREVAL);
643 DEFINE_LSPTR_TYPE(class DebuggerStepper,    LSPTR_STEPPER);
644
645 // Need to be careful not to annoy the compiler here since DT_CONTEXT is a typedef, not a struct.
646 #if defined(RIGHT_SIDE_COMPILE)
647 typedef LsPointer<DT_CONTEXT> LSPTR_CONTEXT;
648 #else  // RIGHT_SIDE_COMPILE
649 typedef LsPointer<DT_CONTEXT> LSPTR_CONTEXT;
650 #endif // RIGHT_SIDE_COMPILE
651
652 DEFINE_LSPTR_TYPE(struct OBJECTHANDLE__,    LSPTR_OBJECTHANDLE);
653 DEFINE_LSPTR_TYPE(class TypeHandleDummyPtr, LSPTR_TYPEHANDLE); // TypeHandle in the LS is not a direct pointer.
654
655 //-----------------------------------------------------------------------------
656 // Definitions for Right-Side ptrs.
657 //-----------------------------------------------------------------------------
658 DEFINE_RSPTR_TYPE(CordbEval,               RSPTR_CORDBEVAL);
659
660
661 //---------------------------------------------------------------------------------------
662 // VMPTR_Base is the base type for an abstraction over pointers into the VM so 
663 // that DBI can treat them as opaque handles. Classes will derive from it to 
664 // provide type-safe Target pointers, which ICD will view as opaque handles.
665 //
666 // Lifetimes:  
667 //   VMPTR_ objects survive across flushing the DAC cache. Therefore, the underlying
668 //   storage must be a target-pointer (and not a marshalled host pointer).
669 //   The RS must ensure they're still in sync with the LS (eg, by
670 //   tracking unload events).
671 //  
672 //
673 // Assumptions:
674 //    These handles are TADDR pointers and must not require any cleanup from DAC/DBI.
675 //    For direct untyped pointers into the VM, use CORDB_ADDRESS.
676 //
677 // Notes:
678 //  1. This helps enforce that DBI goes through the primitives interface
679 //     for all access (and that it doesn't accidentally start calling
680 //     dac-ized methods on the objects)
681 //  2. This isolates DBI from VM headers. 
682 //  3. This isolates DBI from the dac implementation (of DAC_Ptr)
683 //  4. This is distinct from LSPTR because LSPTRs are truly opaque handles, whereas VMPtrs
684 //     move across VM, DAC, and DBI, exposing proper functionality in each component.
685 //  5. VMPTRs are blittable because they are Target Addresses which act as opaque
686 //     handles outside of the Target / Dac-marshaller.  
687 //
688 //---------------------------------------------------------------------------------------
689
690
691 template <typename TTargetPtr, typename TDacPtr>
692 class MSLAYOUT VMPTR_Base
693 {
694     // Underlying pointer into Target address space.
695     // Target pointers are blittable. 
696     // - In Target: can be used as normal local pointers.
697     // - In DAC: must be marshalled to a host-pointer and then they can be used via DAC
698     // - In RS: opaque handles.
699 private:
700     TADDR m_addr;
701
702 public:
703     typedef VMPTR_Base<TTargetPtr,TDacPtr> VMPTR_This;
704
705     // For DBI, VMPTRs are opaque handles.
706     // But the DAC side is allowed to inspect the handles to get at the raw pointer.
707 #if defined(ALLOW_VMPTR_ACCESS)
708     // 
709     // Case 1: Using in DAcDbi implementation
710     //
711
712     // DAC accessor
713     TDacPtr GetDacPtr() const
714     {
715         SUPPORTS_DAC;
716         return TDacPtr(m_addr);
717     }
718
719
720     // This will initialize the handle to a given target-pointer. 
721     // We choose TADDR to make it explicit that it's a target pointer and avoid the risk
722     // of it accidentally getting marshalled to a host pointer. 
723     void SetDacTargetPtr(TADDR addr)
724     {
725         SUPPORTS_DAC;
726         m_addr = addr;
727     }
728     
729     void SetHostPtr(const TTargetPtr * pObject)
730     {
731         SUPPORTS_DAC;
732         m_addr = PTR_HOST_TO_TADDR(pObject);        
733     }
734
735
736 #elif !defined(RIGHT_SIDE_COMPILE)
737     //
738     // Case 2: Used in Left-side. Can get/set from local pointers.
739     //
740
741     // This will set initialize from a Target pointer. Since this is happening in the 
742     // Left-side (Target), the pointer is local.
743     // This is commonly used by the Left-side to create a VMPTR_ for a notification event.
744     void SetRawPtr(TTargetPtr * ptr) 
745     {
746         m_addr = reinterpret_cast<TADDR>(ptr);
747     }
748
749     // This will get the raw underlying target pointer. 
750     // This can be used by inproc Left-side code to unwrap a VMPTR (Eg, for a func-eval
751     // hijack or in-proc worker threads)
752     TTargetPtr * GetRawPtr()
753     {
754         return reinterpret_cast<TTargetPtr*>(m_addr);
755     }
756
757     // Convenience for converting TTargetPtr --> VMPTR
758     static VMPTR_This MakePtr(TTargetPtr * ptr)
759     {
760 #ifdef _PREFAST_
761 #pragma warning(push)
762 #pragma warning(disable:6001) // PREfast warning: Using uninitialize memory 't'
763 #endif // _PREFAST_
764
765         VMPTR_This t;
766         t.SetRawPtr(ptr);
767         return t;
768
769 #ifdef _PREFAST_
770 #pragma warning(pop)
771 #endif // _PREFAST_
772     }
773
774
775 #else
776     //
777     // Case 3: Used in RS. Opaque handles only.
778     //
779 #endif
780
781
782 #ifndef DACCESS_COMPILE
783     // For compatibility, these can be converted to LSPTRs on the RS or LS (case 2 and 3).  We don't allow
784     // this in the DAC case because it's a cast between address spaces which we're trying to eliminate
785     // in the DAC code.
786     // @dbgtodo  inspection: LSPTRs will go away entirely once we've moved completely over to DAC
787     LsPointer<TTargetPtr> ToLsPtr()
788     {
789         return LsPointer<TTargetPtr>::MakePtr( reinterpret_cast<TTargetPtr *>(m_addr));
790     }
791 #endif
792     
793     //
794     // Operators to emulate Pointer semantics.
795     //
796     bool IsNull() { SUPPORTS_DAC; return m_addr == NULL; }
797
798     static VMPTR_This NullPtr()
799     {
800         SUPPORTS_DAC;
801
802 #ifdef _PREFAST_
803 #pragma warning(push)
804 #pragma warning(disable:6001) // PREfast warning: Using uninitialize memory 't'
805 #endif // _PREFAST_
806
807         VMPTR_This dummy;
808         dummy.m_addr = NULL;
809         return dummy;
810
811 #ifdef _PREFAST_
812 #pragma warning(pop)
813 #endif // _PREFAST_
814     }
815
816     bool operator!= (VMPTR_This vmOther) const { SUPPORTS_DAC; return this->m_addr != vmOther.m_addr; }
817     bool operator== (VMPTR_This vmOther) const { SUPPORTS_DAC; return this->m_addr == vmOther.m_addr; }
818 };
819
820 #if defined(ALLOW_VMPTR_ACCESS)
821 // Helper macro to define a VMPTR.
822 // This is used in the DAC case, so this definition connects the pointers up to their DAC values.
823 #define DEFINE_VMPTR(ls_type, dac_ptr_type, ptr_name) \
824     ls_type;  \
825     typedef VMPTR_Base<ls_type, dac_ptr_type> ptr_name;
826
827 #else
828 // Helper macro to define a VMPTR.
829 // This is used in the Right-side and Left-side (but not DAC) case.
830 // This definition explicitly ignores dac_ptr_type to prevent accidental DAC usage.
831 #define DEFINE_VMPTR(ls_type, dac_ptr_type, ptr_name) \
832     ls_type;  \
833     typedef VMPTR_Base<ls_type, void> ptr_name;
834
835 #endif
836
837 // Declare VMPTRs.
838 // The naming convention for instantiating a VMPTR is a 'vm' prefix. 
839 //
840 //           VM definition,         DAC definition,     pretty name for VMPTR
841 DEFINE_VMPTR(class AppDomain,       PTR_AppDomain,      VMPTR_AppDomain);
842
843 // Need to be careful not to annoy the compiler here since DT_CONTEXT is a typedef, not a struct.
844 // DEFINE_VMPTR(struct _CONTEXT,       PTR_CONTEXT,        VMPTR_CONTEXT);
845 #if defined(ALLOW_VMPTR_ACCESS)
846 typedef VMPTR_Base<DT_CONTEXT, PTR_CONTEXT> VMPTR_CONTEXT;
847 #else
848 typedef VMPTR_Base<DT_CONTEXT, void > VMPTR_CONTEXT;
849 #endif
850
851 // DomainFile is a base-class for a CLR module, with app-domain affinity.
852 // For domain-neutral modules (like mscorlib), there is a DomainFile instance
853 // for each appdomain the module lives in. 
854 // This is the canonical handle ICorDebug uses to a CLR module. 
855 DEFINE_VMPTR(class DomainFile,      PTR_DomainFile,     VMPTR_DomainFile);
856 DEFINE_VMPTR(class Module,          PTR_Module,         VMPTR_Module);
857
858 // DomainAssembly derives from DomainFile and represents a manifest module. 
859 DEFINE_VMPTR(class DomainAssembly,  PTR_DomainAssembly, VMPTR_DomainAssembly);
860 DEFINE_VMPTR(class Assembly,        PTR_Assembly,       VMPTR_Assembly);
861
862 DEFINE_VMPTR(class PEFile,          PTR_PEFile,         VMPTR_PEFile); 
863 DEFINE_VMPTR(class MethodDesc,      PTR_MethodDesc,     VMPTR_MethodDesc);
864 DEFINE_VMPTR(class FieldDesc,       PTR_FieldDesc,      VMPTR_FieldDesc);
865
866 // ObjectHandle is a safe way to represent an object into the GC heap. It gets updated
867 // when a GC occurs.
868 DEFINE_VMPTR(struct OBJECTHANDLE__, TADDR,              VMPTR_OBJECTHANDLE);
869
870 DEFINE_VMPTR(class TypeHandle,      PTR_TypeHandle,     VMPTR_TypeHandle);   
871
872 // A VMPTR_Thread represents a thread that has entered the runtime at some point. 
873 // It may or may not have executed managed code yet; and it may or may not have managed code
874 // on its callstack.
875 DEFINE_VMPTR(class Thread,          PTR_Thread,         VMPTR_Thread);
876
877 DEFINE_VMPTR(class Object,          PTR_Object,         VMPTR_Object);
878
879 DEFINE_VMPTR(class CrstBase,        PTR_Crst,           VMPTR_Crst);
880 DEFINE_VMPTR(class SimpleRWLock,    PTR_SimpleRWLock,   VMPTR_SimpleRWLock);
881 DEFINE_VMPTR(class SimpleRWLock,    PTR_SimpleRWLock,   VMPTR_RWLock);
882 DEFINE_VMPTR(struct ReJitInfo,       PTR_ReJitInfo,      VMPTR_ReJitInfo);
883 DEFINE_VMPTR(struct SharedReJitInfo, PTR_SharedReJitInfo, VMPTR_SharedReJitInfo);
884 DEFINE_VMPTR(class NativeCodeVersionNode, PTR_NativeCodeVersionNode, VMPTR_NativeCodeVersionNode);
885 DEFINE_VMPTR(class ILCodeVersionNode, PTR_ILCodeVersionNode, VMPTR_ILCodeVersionNode);
886
887 typedef CORDB_ADDRESS GENERICS_TYPE_TOKEN;
888
889
890 //-----------------------------------------------------------------------------
891 // We pass some fixed size strings in the IPC block.
892 // Helper class to wrap the buffer and protect against buffer overflows.
893 // This should be binary compatible w/ a wchar[] array.
894 //-----------------------------------------------------------------------------
895
896 template <int nMaxLengthIncludingNull>
897 class MSLAYOUT EmbeddedIPCString
898 {
899 public:
900     // Set, caller responsibility that wcslen(pData) < nMaxLengthIncludingNull
901     void SetString(const WCHAR * pData)
902     {
903         // If the string doesn't fit into the buffer, that's an issue (and so this is a real
904         // assert, not just a simplifying assumption). To fix it, either:
905         // - make the buffer larger
906         // - don't pass the string as an embedded string in the IPC block.
907         // This will truncate (rather than AV on the RS).
908         int ret;
909         ret = SafeCopy(pData);
910
911         // See comment above - caller should guarantee that buffer is large enough.
912         _ASSERTE(ret != STRUNCATE);
913     }
914
915     // Set a string from a substring. This will truncate if necessary.
916     void SetStringTruncate(const WCHAR * pData)
917     {
918         // ignore return value because truncation is ok.
919         SafeCopy(pData);
920     }
921
922     const WCHAR * GetString()
923     {
924         // For a null-termination just in case an issue in the debuggee process
925         // yields a malformed string.
926         m_data[nMaxLengthIncludingNull - 1] = W('\0');
927         return &m_data[0];
928     }
929     int GetMaxSize() const { return nMaxLengthIncludingNull; }
930
931 private:
932     int SafeCopy(const WCHAR * pData)
933     {
934         return wcsncpy_s(
935             m_data, nMaxLengthIncludingNull,
936             pData, _TRUNCATE);
937     }
938     WCHAR m_data[nMaxLengthIncludingNull];
939 };
940
941 //
942 // Types of events that can be sent between the Runtime Controller and
943 // the Debugger Interface. Some of these events are one way only, while
944 // others go both ways. The grouping of the event numbers is an attempt
945 // to show this distinction and perhaps even allow generic operations
946 // based on the type of the event.
947 //
948 enum DebuggerIPCEventType
949 {
950 #define IPC_EVENT_TYPE0(type, val)  type = val,
951 #define IPC_EVENT_TYPE1(type, val)  type = val,
952 #define IPC_EVENT_TYPE2(type, val)  type = val,
953 #include "dbgipceventtypes.h"
954 #undef IPC_EVENT_TYPE2
955 #undef IPC_EVENT_TYPE1
956 #undef IPC_EVENT_TYPE0
957 };
958
959 #ifdef _DEBUG
960
961 // This is a static debugging structure to help breaking at the right place.
962 // Debug only. This is to track the number of events that have been happened so far.
963 // User can choose to set break point base on the number of events.
964 // Variables are named as the event name with prefix m_iDebugCount. For example
965 // m_iDebugCount_DB_IPCE_BREAKPOINT if for event DB_IPCE_BREAKPOINT.
966 struct MSLAYOUT DebugEventCounter
967 {
968 // we don't need the event type 0
969 #define IPC_EVENT_TYPE0(type, val)
970 #define IPC_EVENT_TYPE1(type, val)  int m_iDebugCount_##type;
971 #define IPC_EVENT_TYPE2(type, val)  int m_iDebugCount_##type;
972 #include "dbgipceventtypes.h"
973 #undef IPC_EVENT_TYPE2
974 #undef IPC_EVENT_TYPE1
975 #undef IPC_EVENT_TYPE0
976 };
977 #endif // _DEBUG
978
979
980 #if !defined(DACCESS_COMPILE)
981
982 struct MSLAYOUT IPCEventTypeNameMapping
983     {
984             DebuggerIPCEventType    eventType;
985             const char *            eventName;
986 };
987
988 extern const IPCEventTypeNameMapping DECLSPEC_SELECTANY DbgIPCEventTypeNames[] =
989 {
990     #define IPC_EVENT_TYPE0(type, val)  { type, #type },
991     #define IPC_EVENT_TYPE1(type, val)  { type, #type },
992     #define IPC_EVENT_TYPE2(type, val)  { type, #type },
993     #include "dbgipceventtypes.h"
994     #undef IPC_EVENT_TYPE2
995     #undef IPC_EVENT_TYPE1
996     #undef IPC_EVENT_TYPE0
997     { DB_IPCE_INVALID_EVENT, "DB_IPCE_Error" }
998 };
999
1000 const size_t nameCount = sizeof(DbgIPCEventTypeNames) / sizeof(DbgIPCEventTypeNames[0]);
1001
1002
1003 struct MSLAYOUT IPCENames // We use a class/struct so that the function can remain in a shared header file
1004 {
1005     static const DebuggerIPCEventType GetEventType(__in_z char * strEventType)
1006     {
1007         // pass in the string of event name and find the matching enum value
1008         // This is a linear search which is pretty slow. However, this is only used
1009         // at startup time when debug assert is turn on and with registry key set. So it is not that bad.
1010         //
1011         for (size_t i = 0; i < nameCount; i++)
1012         {
1013             if (_stricmp(DbgIPCEventTypeNames[i].eventName, strEventType) == 0)
1014                 return DbgIPCEventTypeNames[i].eventType;
1015         }
1016         return DB_IPCE_INVALID_EVENT;
1017     }
1018     static const char * GetName(DebuggerIPCEventType eventType)
1019     {
1020
1021         enum DbgIPCEventTypeNum
1022         {
1023         #define IPC_EVENT_TYPE0(type, val)  type##_Num,
1024         #define IPC_EVENT_TYPE1(type, val)  type##_Num,
1025         #define IPC_EVENT_TYPE2(type, val)  type##_Num,
1026         #include "dbgipceventtypes.h"
1027         #undef IPC_EVENT_TYPE2
1028         #undef IPC_EVENT_TYPE1
1029         #undef IPC_EVENT_TYPE0
1030         };
1031
1032         unsigned int i, lim;
1033
1034         if (eventType < DB_IPCE_DEBUGGER_FIRST)
1035         {
1036             i = DB_IPCE_RUNTIME_FIRST_Num + 1;
1037             lim = DB_IPCE_DEBUGGER_FIRST_Num;
1038         }
1039         else
1040         {
1041             i = DB_IPCE_DEBUGGER_FIRST_Num + 1;
1042             lim = nameCount;
1043         }
1044
1045         for (/**/; i < lim; i++)
1046         {
1047             if (DbgIPCEventTypeNames[i].eventType == eventType)
1048                 return DbgIPCEventTypeNames[i].eventName;
1049         }
1050
1051         return DbgIPCEventTypeNames[nameCount - 1].eventName;
1052     }
1053 };
1054
1055 #endif // !DACCESS_COMPILE
1056
1057 //
1058 // NOTE:  CPU-specific values below!
1059 //
1060 // DebuggerREGDISPLAY is very similar to the EE REGDISPLAY structure. It holds
1061 // register values that can be saved over calls for each frame in a stack
1062 // trace.
1063 //
1064 // DebuggerIPCE_FloatCount is the number of doubles in the processor's
1065 // floating point stack.
1066 //
1067 // <TODO>Note: We used to just pass the values of the registers for each frame to the Right Side, but I had to add in the
1068 // address of each register, too, to support using enregistered variables on non-leaf frames as args to a func eval. Its
1069 // very, very possible that we would rework the entire code base to just use the register's address instead of passing
1070 // both, but its way, way too late in V1 to undertake that, so I'm just using these addresses to suppport our one func
1071 // eval case. Clearly, this needs to be cleaned up post V1.
1072 //
1073 // -- Fri Feb 09 11:21:24 2001</TODO>
1074 //
1075
1076 struct MSLAYOUT DebuggerREGDISPLAY
1077 {
1078 #if defined(DBG_TARGET_X86)
1079     #define DebuggerIPCE_FloatCount 8
1080
1081     SIZE_T  Edi;
1082     void   *pEdi;
1083     SIZE_T  Esi;
1084     void   *pEsi;
1085     SIZE_T  Ebx;
1086     void   *pEbx;
1087     SIZE_T  Edx;
1088     void   *pEdx;
1089     SIZE_T  Ecx;
1090     void   *pEcx;
1091     SIZE_T  Eax;
1092     void   *pEax;
1093     SIZE_T  FP;
1094     void   *pFP;
1095     SIZE_T  SP;
1096     SIZE_T  PC;
1097
1098 #elif defined(DBG_TARGET_AMD64)
1099     #define DebuggerIPCE_FloatCount 16
1100
1101     SIZE_T  Rax;
1102     void   *pRax;
1103     SIZE_T  Rcx;
1104     void   *pRcx;
1105     SIZE_T  Rdx;
1106     void   *pRdx;
1107     SIZE_T  Rbx;
1108     void   *pRbx;
1109     SIZE_T  Rbp;
1110     void   *pRbp;
1111     SIZE_T  Rsi;
1112     void   *pRsi;
1113     SIZE_T  Rdi;
1114     void   *pRdi;
1115
1116     SIZE_T  R8;
1117     void   *pR8;
1118     SIZE_T  R9;
1119     void   *pR9;
1120     SIZE_T  R10;
1121     void   *pR10;
1122     SIZE_T  R11;
1123     void   *pR11;
1124     SIZE_T  R12;
1125     void   *pR12;
1126     SIZE_T  R13;
1127     void   *pR13;
1128     SIZE_T  R14;
1129     void   *pR14;
1130     SIZE_T  R15;
1131     void   *pR15;
1132
1133     SIZE_T  SP;
1134     SIZE_T  PC;
1135 #elif defined(DBG_TARGET_ARM)
1136     #define DebuggerIPCE_FloatCount 32
1137
1138     SIZE_T  R0;
1139     void   *pR0;
1140     SIZE_T  R1;
1141     void   *pR1;
1142     SIZE_T  R2;
1143     void   *pR2;
1144     SIZE_T  R3;
1145     void   *pR3;
1146     SIZE_T  R4;
1147     void   *pR4;
1148     SIZE_T  R5;
1149     void   *pR5;
1150     SIZE_T  R6;
1151     void   *pR6;
1152     SIZE_T  R7;
1153     void   *pR7;
1154     SIZE_T  R8;
1155     void   *pR8;
1156     SIZE_T  R9;
1157     void   *pR9;
1158     SIZE_T  R10;
1159     void   *pR10;
1160     SIZE_T  R11;
1161     void   *pR11;
1162     SIZE_T  R12;
1163     void   *pR12;
1164     SIZE_T  SP;
1165     void   *pSP;
1166     SIZE_T  LR;
1167     void   *pLR;
1168     SIZE_T  PC;
1169     void   *pPC;
1170 #elif defined(DBG_TARGET_ARM64)
1171     #define DebuggerIPCE_FloatCount 32
1172
1173     SIZE_T  X[29];
1174     SIZE_T  SP;
1175     SIZE_T  FP;
1176     SIZE_T  LR;
1177     SIZE_T  PC;
1178 #else
1179     #define DebuggerIPCE_FloatCount 1
1180
1181     SIZE_T PC;
1182     SIZE_T FP;
1183     SIZE_T SP;
1184     void   *pFP;
1185 #endif
1186 };
1187
1188 inline LPVOID GetSPAddress(const DebuggerREGDISPLAY * display)
1189 {
1190     return (LPVOID)&display->SP;
1191 }
1192
1193 #if !defined(DBG_TARGET_AMD64) && !defined(DBG_TARGET_ARM)
1194 inline LPVOID GetFPAddress(const DebuggerREGDISPLAY * display)
1195 {
1196     return (LPVOID)&display->FP;
1197 }
1198 #endif // !DBG_TARGET_AMD64
1199
1200
1201 class MSLAYOUT FramePointer
1202 {
1203 friend bool IsCloserToLeaf(FramePointer fp1, FramePointer fp2);
1204 friend bool IsCloserToRoot(FramePointer fp1, FramePointer fp2);
1205 friend bool IsEqualOrCloserToLeaf(FramePointer fp1, FramePointer fp2);
1206 friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2);
1207
1208 public:
1209
1210     static FramePointer MakeFramePointer(LPVOID sp)
1211     {
1212         LIMITED_METHOD_DAC_CONTRACT;
1213         FramePointer fp;
1214         fp.m_sp = sp;
1215         return fp;
1216     }
1217
1218     static FramePointer MakeFramePointer(UINT_PTR sp)
1219     {
1220         SUPPORTS_DAC;
1221         return MakeFramePointer((LPVOID)sp);
1222     }
1223
1224     inline bool operator==(FramePointer fp)
1225     {
1226         return (m_sp == fp.m_sp);
1227     }
1228
1229     inline bool operator!=(FramePointer fp)
1230     {
1231         return !(*this == fp);
1232     }
1233
1234     // This is needed because on the RS, the m_id values of CordbFrame and
1235     // CordbChain are really FramePointers.
1236     LPVOID GetSPValue() const
1237     {
1238         return m_sp;
1239     }
1240
1241
1242 private:
1243     // Declare some private constructors which signatures matching common usage of FramePointer
1244     // to prevent people from accidentally assigning a pointer to a FramePointer().
1245     FramePointer &operator=(LPVOID sp);
1246     FramePointer &operator=(BYTE* sp);
1247     FramePointer &operator=(const BYTE* sp);
1248
1249     LPVOID m_sp;
1250 };
1251
1252 // For non-IA64 platforms, we use stack pointers as frame pointers.
1253 // (Stack grows towards smaller address.)
1254 #define LEAF_MOST_FRAME FramePointer::MakeFramePointer((LPVOID)NULL)
1255 #define ROOT_MOST_FRAME FramePointer::MakeFramePointer((LPVOID)-1)
1256
1257 static_assert_no_msg(sizeof(FramePointer) == sizeof(void*));
1258
1259
1260 inline bool IsCloserToLeaf(FramePointer fp1, FramePointer fp2)
1261 {
1262     return (fp1.m_sp < fp2.m_sp);
1263 }
1264
1265 inline bool IsCloserToRoot(FramePointer fp1, FramePointer fp2)
1266 {
1267     return (fp1.m_sp > fp2.m_sp);
1268 }
1269
1270 inline bool IsEqualOrCloserToLeaf(FramePointer fp1, FramePointer fp2)
1271 {
1272     return !IsCloserToRoot(fp1, fp2);
1273 }
1274
1275 inline bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2)
1276 {
1277     return !IsCloserToLeaf(fp1, fp2);
1278 }
1279
1280
1281 // struct DebuggerIPCE_FuncData:   DebuggerIPCE_FuncData holds data
1282 // to describe a given function, its
1283 // class, and a little bit about the code for the function. This is used
1284 // in the stack trace result data to pass function information back that
1285 // may be needed. Its also used when getting data about a specific function.
1286 //
1287 // void* nativeStartAddressPtr: Ptr to CORDB_ADDRESS, which is
1288 //          the address of the real start address of the native code.
1289 //          This field will be NULL only if the method hasn't been JITted
1290 //          yet (and thus no code is available).  Otherwise, it will be
1291 //          the adress of a CORDB_ADDRESS in the remote memory.  This
1292 //          CORDB_ADDRESS may be NULL, in which case the code is unavailable
1293 //          has been pitched (return CORDBG_E_CODE_NOT_AVAILABLE)
1294 //
1295 // SIZE_T nVersion: The version of the code that this instance of the
1296 //          function is using.
1297 struct MSLAYOUT DebuggerIPCE_FuncData
1298 {
1299     mdMethodDef funcMetadataToken;
1300     VMPTR_DomainFile vmDomainFile;
1301
1302     mdTypeDef   classMetadataToken;
1303
1304     void*       ilStartAddress;
1305     SIZE_T      ilSize;
1306
1307     SIZE_T      currentEnCVersion;
1308
1309     mdSignature  localVarSigToken;
1310
1311
1312 };
1313
1314 // struct DebuggerIPCE_JITFuncData:   DebuggerIPCE_JITFuncData holds
1315 // a little bit about the JITted code for the function.
1316 //
1317 // void* nativeStartAddressPtr: Ptr to CORDB_ADDRESS, which is
1318 //          the address of the real start address of the native code.
1319 //          This field will be NULL only if the method hasn't been JITted
1320 //          yet (and thus no code is available).  Otherwise, it will be
1321 //          the address of a CORDB_ADDRESS in the remote memory.  This
1322 //          CORDB_ADDRESS may be NULL, in which case the code is unavailable
1323 //          or has been pitched (return CORDBG_E_CODE_NOT_AVAILABLE)
1324 //
1325 // SIZE_T nativeSize: Size of the native code.
1326 //
1327 // SIZE_T nativeOffset: Offset from the beginning of the function,
1328 //          in bytes.  This may be non-zero even when nativeStartAddressPtr
1329 //          is NULL
1330 // void * nativeCodeJITInfoToken: An opaque value to hand back to the left
1331 //          side when fetching the JITInfo for the native code, i.e. the
1332 //          IL->native maps for the variables.  This may be NULL if no JITInfo is available.
1333 // void * nativeCodeMethodDescToken: An opaque value to hand back to the left
1334 //          side when fetching the code.  In addition this token can act as the
1335 //          unique identity for the native code in the case where there are
1336 //          multiple blobs of native code per IL method (i.e. if the method is
1337 //          generic code of some kind)
1338 // BOOL isInstantiatedGeneric: Indicates if the method is
1339 //          generic code of some kind.
1340 // BOOL jsutAfterILThrow: indicates that code just threw a software exception and
1341 //          nativeOffset points to an instruction just after [call IL_Throw].
1342 //          This is being used to figure out a real offset of the exception origin.  
1343 //          By subtracting STACKWALK_CONTROLPC_ADJUST_OFFSET from nativeOffset you can get 
1344 //          an address somewhere inside [call IL_Throw] instruction.
1345 // void *ilToNativeMapAddr etc.: If nativeCodeJITInfoToken is not NULL then these
1346 //          specify the table giving the mapping of IPs.
1347 struct MSLAYOUT DebuggerIPCE_JITFuncData
1348 {
1349     TADDR       nativeStartAddressPtr;
1350     SIZE_T      nativeHotSize;
1351
1352     // If we have a cold region, need its size & the pointer to where starts.
1353     TADDR       nativeStartAddressColdPtr;
1354     SIZE_T      nativeColdSize;
1355
1356
1357     SIZE_T      nativeOffset;
1358     LSPTR_DJI   nativeCodeJITInfoToken;
1359     VMPTR_MethodDesc vmNativeCodeMethodDescToken;
1360
1361 #ifdef WIN64EXCEPTIONS
1362     BOOL         fIsFilterFrame;
1363     SIZE_T       parentNativeOffset;
1364     FramePointer fpParentOrSelf;
1365 #endif // WIN64EXCEPTIONS
1366
1367     // indicates if the MethodDesc is a generic function or a method inside a generic class (or
1368     // both!).
1369     BOOL         isInstantiatedGeneric;
1370
1371     // this is the version of the jitted code
1372     SIZE_T       enCVersion;
1373
1374     BOOL         jsutAfterILThrow;
1375 };
1376
1377 //
1378 // DebuggerIPCE_STRData holds data for each stack frame or chain. This data is passed
1379 // from the RC to the DI during a stack walk.
1380 //
1381 #if defined(_MSC_VER)
1382 #pragma warning( push )
1383 #pragma warning( disable:4324 ) // the compiler pads a structure to comply with alignment requirements
1384 #endif                          // ARM context structures have a 16-byte alignment requirement
1385 struct MSLAYOUT DebuggerIPCE_STRData
1386 {
1387     FramePointer            fp;
1388     // @dbgtodo  stackwalker/shim- Ideally we should be able to get rid of the DebuggerREGDISPLAY and just use the CONTEXT.
1389     DT_CONTEXT              ctx;
1390     DebuggerREGDISPLAY      rd;
1391     bool                    quicklyUnwound;
1392
1393     VMPTR_AppDomain         vmCurrentAppDomainToken;
1394
1395
1396     enum EType
1397     {
1398         cMethodFrame = 0,
1399         cChain,
1400         cStubFrame,
1401         cRuntimeNativeFrame
1402     } eType;
1403
1404     union MSLAYOUT
1405     {
1406         // Data for a chain
1407         struct MSLAYOUT
1408         {
1409             CorDebugChainReason chainReason;
1410             bool                managed;
1411         } u;
1412
1413         // Data for a Method
1414         struct MSLAYOUT
1415         {
1416             struct DebuggerIPCE_FuncData funcData;
1417             struct DebuggerIPCE_JITFuncData jitFuncData;
1418             SIZE_T                       ILOffset;
1419             CorDebugMappingResult        mapping;
1420
1421             bool        fVarArgs;
1422
1423             // Indicates whether the managed method has any metadata.
1424             // Some dynamic methods such as IL stubs and LCG methods don't have any metadata.
1425             // This is used only by the V3 stackwalker, not the V2 one, because we only 
1426             // expose dynamic methods as real stack frames in V3.
1427             bool        fNoMetadata;
1428
1429             TADDR       taAmbientESP;
1430
1431             GENERICS_TYPE_TOKEN exactGenericArgsToken;
1432             DWORD               dwExactGenericArgsTokenIndex;
1433
1434         } v;
1435
1436         // Data for an Stub Frame.
1437         struct MSLAYOUT
1438         {
1439             mdMethodDef funcMetadataToken;
1440             VMPTR_DomainFile vmDomainFile;
1441             VMPTR_MethodDesc vmMethodDesc;
1442             CorDebugInternalFrameType frameType;
1443         } stubFrame;
1444
1445     };
1446 };
1447 #if defined(_MSC_VER)
1448 #pragma warning( pop )
1449 #endif
1450
1451 //
1452 // DebuggerIPCE_BasicTypeData and DebuggerIPCE_ExpandedTypeData
1453 // hold data for each type sent across the
1454 // boundary, whether it be a constructed type List<String> or a non-constructed
1455 // type such as String, Foo or Object.
1456 //
1457 // Logically speaking DebuggerIPCE_BasicTypeData might just be "typeHandle", as
1458 // we could then send further events to ask what the elementtype, typeToken and moduleToken
1459 // are for the type handle.  But as
1460 // nearly all types are non-generic we send across even the basic type information in
1461 // the slightly expanded form shown below, sending the element type and the
1462 // tokens with the type handle itself. The fields debuggerModuleToken, metadataToken and typeHandle
1463 // are only used as follows:
1464 //                                   elementType    debuggerModuleToken metadataToken      typeHandle
1465 //     E_T_INT8    :                  E_T_INT8         No                     No              No
1466 //     Boxed E_T_INT8:                E_T_CLASS        No                     No              No
1467 //     E_T_CLASS, non-generic class:  E_T_CLASS       Yes                    Yes              No
1468 //     E_T_VALUETYPE, non-generic:    E_T_VALUETYPE   Yes                    Yes              No
1469 //     E_T_CLASS,     generic class:  E_T_CLASS       Yes                    Yes             Yes
1470 //     E_T_VALUETYPE, generic class:  E_T_VALUETYPE   Yes                    Yes             Yes
1471 //     E_T_BYREF                   :  E_T_BYREF        No                     No             Yes
1472 //     E_T_PTR                     :  E_T_PTR          No                     No             Yes
1473 //     E_T_ARRAY etc.              :  E_T_ARRAY        No                     No             Yes
1474 //     E_T_FNPTR etc.              :  E_T_FNPTR        No                     No             Yes
1475 // This allows us to always set "typeHandle" to NULL except when dealing with highly nested
1476 // types or function-pointer types (the latter are too complexe to transfer over in one hit).
1477 //
1478
1479 struct MSLAYOUT DebuggerIPCE_BasicTypeData
1480 {
1481     CorElementType  elementType;
1482     mdTypeDef       metadataToken;
1483     VMPTR_Module     vmModule;
1484     VMPTR_DomainFile vmDomainFile;
1485     VMPTR_TypeHandle vmTypeHandle;
1486 };
1487
1488 // DebuggerIPCE_ExpandedTypeData contains more information showing further
1489 // details for array types, byref types etc.
1490 // Whenever you fetch type information from the left-side
1491 // you get back one of these.  These in turn contain further
1492 // DebuggerIPCE_BasicTypeData's and typeHandles which you can
1493 // then query to get further information about the type parameters.
1494 // This copes with the nested cases, e.g. jagged arrays,
1495 // String ****, &(String*), Pair<String,Pair<String>>
1496 // and so on.
1497 //
1498 // So this type information is not "fully expanded", it's just a little
1499 // more detail then DebuggerIPCE_BasicTypeData.  For type
1500 // instantiatons (e.g. List<int>) and
1501 // function pointer types you will need to make further requests for
1502 // information about the type parameters.
1503 // For array types there is always only one type parameter so
1504 // we include that as part of the expanded data.
1505 //
1506 //
1507 struct MSLAYOUT DebuggerIPCE_ExpandedTypeData
1508 {
1509     CorElementType  elementType; // Note this is _never_ E_T_VAR, E_T_WITH or E_T_MVAR
1510     union MSLAYOUT
1511     {
1512         // used for E_T_CLASS and E_T_VALUECLASS, E_T_PTR, E_T_BYREF etc.
1513         // For non-constructed E_T_CLASS or E_T_VALUECLASS the tokens will be set and the typeHandle will be NULL
1514         // For constructed E_T_CLASS or E_T_VALUECLASS the tokens will be set and the typeHandle will be non-NULL
1515         // For E_T_PTR etc. the tokens will be NULL and the typeHandle will be non-NULL.
1516         struct MSLAYOUT
1517          {
1518             mdTypeDef       metadataToken;
1519             VMPTR_Module vmModule;
1520             VMPTR_DomainFile vmDomainFile;
1521             VMPTR_TypeHandle typeHandle; // if non-null then further fetches will be needed to get type arguments
1522         } ClassTypeData;
1523
1524         // used for E_T_PTR, E_T_BYREF etc.
1525         struct MSLAYOUT
1526          {
1527             DebuggerIPCE_BasicTypeData unaryTypeArg;  // used only when sending back to debugger
1528         } UnaryTypeData;
1529
1530
1531         // used for E_T_ARRAY etc.
1532         struct MSLAYOUT
1533         {
1534           DebuggerIPCE_BasicTypeData arrayTypeArg; // used only when sending back to debugger
1535             DWORD           arrayRank;
1536         } ArrayTypeData;
1537
1538         // used for E_T_FNPTR
1539         struct MSLAYOUT
1540          {
1541             VMPTR_TypeHandle typeHandle; // if non-null then further fetches needed to get type arguments
1542         } NaryTypeData;
1543
1544     };
1545 };
1546
1547 // DebuggerIPCE_TypeArgData is used when sending type arguments
1548 // across to a funceval.  It contains the DebuggerIPCE_ExpandedTypeData describing the
1549 // essence of the type, but the typeHandle and other
1550 // BasicTypeData fields should be zero and will be ignored.
1551 // The DebuggerIPCE_ExpandedTypeData is then followed
1552 // by the required number of type arguments, each of which
1553 // will be a further DebuggerIPCE_TypeArgData record in the stream of
1554 // flattened type argument data.
1555 struct MSLAYOUT DebuggerIPCE_TypeArgData
1556 {
1557     DebuggerIPCE_ExpandedTypeData  data;
1558     unsigned int                   numTypeArgs; // number of immediate children on the type tree
1559 };
1560
1561
1562 //
1563 // DebuggerIPCE_ObjectData holds the results of a
1564 // GetAndSendObjectInfo, i.e., all the info about an object that the
1565 // Right Side would need to access it. (This include array, string,
1566 // and nstruct info.)
1567 //
1568 struct MSLAYOUT DebuggerIPCE_ObjectData
1569 {
1570     void           *objRef;
1571     bool            objRefBad;
1572     SIZE_T          objSize;
1573
1574     // Offset from the beginning of the object to the beginning of the first field
1575     SIZE_T          objOffsetToVars;
1576
1577     // The type of the object....
1578     struct DebuggerIPCE_ExpandedTypeData objTypeData;
1579
1580     union MSLAYOUT
1581     {
1582         struct MSLAYOUT
1583         {
1584             SIZE_T          length;
1585             SIZE_T          offsetToStringBase;
1586         } stringInfo;
1587
1588         struct MSLAYOUT
1589         {
1590             SIZE_T          rank;
1591             SIZE_T          offsetToArrayBase;
1592             SIZE_T          offsetToLowerBounds; // 0 if not present
1593             SIZE_T          offsetToUpperBounds; // 0 if not present
1594             SIZE_T          componentCount;
1595             SIZE_T          elementSize;
1596         } arrayInfo;
1597
1598         struct MSLAYOUT
1599         {
1600             struct DebuggerIPCE_BasicTypeData typedByrefType; // the type of the thing contained in a typedByref...
1601         } typedByrefInfo;
1602     };
1603 };
1604
1605 //
1606 // Remote enregistered info used by CordbValues and for passing
1607 // variable homes between the left and right sides during a func eval.
1608 //
1609
1610 enum RemoteAddressKind
1611 {
1612     RAK_NONE = 0,
1613     RAK_REG,
1614     RAK_REGREG,
1615     RAK_REGMEM,
1616     RAK_MEMREG,
1617     RAK_FLOAT,
1618     RAK_END
1619 };
1620
1621 const CORDB_ADDRESS kLeafFrameRegAddr = 0;
1622 const CORDB_ADDRESS kNonLeafFrameRegAddr = (CORDB_ADDRESS)(-1);
1623
1624 struct MSLAYOUT RemoteAddress
1625 {
1626     RemoteAddressKind    kind;
1627     void                *frame;
1628
1629     CorDebugRegister     reg1;
1630     void                *reg1Addr;
1631     SIZE_T               reg1Value;         // this is the actual value of the register
1632
1633     union MSLAYOUT
1634     {
1635         struct MSLAYOUT
1636         {
1637             CorDebugRegister  reg2;
1638             void             *reg2Addr;
1639             SIZE_T            reg2Value;    // this is the actual value of the register
1640         } u;
1641
1642         CORDB_ADDRESS    addr;
1643         DWORD            floatIndex;
1644     };
1645 };
1646
1647 //
1648 // DebuggerIPCE_FuncEvalType specifies the type of a function
1649 // evaluation that will occur.
1650 //
1651 enum DebuggerIPCE_FuncEvalType
1652 {
1653     DB_IPCE_FET_NORMAL,
1654     DB_IPCE_FET_NEW_OBJECT,
1655     DB_IPCE_FET_NEW_OBJECT_NC,
1656     DB_IPCE_FET_NEW_STRING,
1657     DB_IPCE_FET_NEW_ARRAY,
1658     DB_IPCE_FET_RE_ABORT
1659 };
1660
1661
1662 enum NameChangeType
1663 {
1664     APP_DOMAIN_NAME_CHANGE,
1665     THREAD_NAME_CHANGE
1666 };
1667
1668 //
1669 // DebuggerIPCE_FuncEvalArgData holds data for each argument to a
1670 // function evaluation.
1671 //
1672 struct MSLAYOUT DebuggerIPCE_FuncEvalArgData
1673 {
1674     RemoteAddress     argHome;  // enregistered variable home
1675     void             *argAddr;  // address if not enregistered
1676     CorElementType    argElementType;
1677     unsigned int      fullArgTypeNodeCount; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types)
1678     void             *fullArgType; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types)
1679     BYTE              argLiteralData[8]; // copy of generic value data
1680     bool              argIsLiteral; // true if value is in argLiteralData
1681     bool              argIsHandleValue; // true if argAddr is OBJECTHANDLE
1682 };
1683
1684
1685 //
1686 // DebuggerIPCE_FuncEvalInfo holds info necessary to setup a func eval
1687 // operation.
1688 //
1689 struct MSLAYOUT DebuggerIPCE_FuncEvalInfo
1690 {
1691     VMPTR_Thread               vmThreadToken;
1692     DebuggerIPCE_FuncEvalType  funcEvalType;
1693     mdMethodDef                funcMetadataToken;
1694     mdTypeDef                  funcClassMetadataToken;
1695     VMPTR_DomainFile           vmDomainFile;
1696     RSPTR_CORDBEVAL            funcEvalKey;
1697     bool                       evalDuringException;
1698
1699     unsigned int               argCount;
1700     unsigned int               genericArgsCount;
1701     unsigned int               genericArgsNodeCount;
1702
1703     SIZE_T                     stringSize;
1704
1705     SIZE_T                     arrayRank;
1706 };
1707
1708
1709 //
1710 // Used in DebuggerIPCFirstChanceData. This tells the LS what action to take within the hijack
1711 //
1712 enum HijackAction
1713 {
1714     HIJACK_ACTION_EXIT_UNHANDLED,
1715     HIJACK_ACTION_EXIT_HANDLED,
1716     HIJACK_ACTION_WAIT
1717 };
1718
1719 //
1720 // DebuggerIPCFirstChanceData holds info communicated from the LS to the RS when signaling that an exception does not
1721 // belong to the runtime from a first chance hijack. This is used when Win32 debugging only.
1722 //
1723 struct MSLAYOUT DebuggerIPCFirstChanceData
1724 {
1725     LSPTR_CONTEXT     pLeftSideContext;
1726     HijackAction      action;
1727     UINT              debugCounter;
1728 };
1729
1730 //
1731 // DebuggerIPCSecondChanceData holds info communicated from the RS
1732 // to the LS when setting up a second chance exception hijack. This is
1733 // used when Win32 debugging only.
1734 //
1735 struct MSLAYOUT DebuggerIPCSecondChanceData
1736 {
1737     DT_CONTEXT       threadContext;
1738 };
1739
1740
1741
1742 //-----------------------------------------------------------------------------
1743 // This struct holds pointer from the LS and needs to copy to
1744 // the RS. We have to free the memory on the RS.
1745 // The transfer function is called when the RS first reads the event. At this point, 
1746 // the LS is stopped while sending the event. Thus the LS pointers only need to be
1747 // valid while the LS is in SendIPCEvent.
1748 //
1749 // Since this data is in an IPC/Marshallable block, it can't have any Ctors (holders)
1750 // in it. 
1751 //-----------------------------------------------------------------------------
1752 struct MSLAYOUT Ls_Rs_BaseBuffer
1753 {
1754 #ifdef RIGHT_SIDE_COMPILE
1755 protected:
1756     // copy data can happen on both LS and RS. In LS case,
1757     // ReadProcessMemory is really reading from its own process memory.
1758     //
1759     void CopyLSDataToRSWorker(ICorDebugDataTarget * pTargethProcess);
1760     
1761     // retrieve the RS data and own it
1762     BYTE *TransferRSDataWorker()
1763     {
1764         BYTE *pbRS = m_pbRS;
1765         m_pbRS = NULL;
1766         return pbRS;
1767     }
1768 public:
1769     
1770
1771     void CleanUp()
1772     {
1773         if (m_pbRS != NULL)
1774         {
1775             delete [] m_pbRS;
1776             m_pbRS = NULL;
1777         }
1778     }
1779 #else
1780 public:
1781     // Only LS can call this API
1782     void SetLsData(BYTE *pbLS, DWORD cbSize)
1783     {
1784         m_pbRS = NULL;
1785         m_pbLS = pbLS;
1786         m_cbSize = cbSize;
1787     }
1788 #endif // RIGHT_SIDE_COMPILE
1789
1790 public:
1791     // Common APIs.
1792     DWORD  GetSize() { return m_cbSize; }
1793
1794
1795
1796 protected:
1797     // Size of data in bytes 
1798     DWORD  m_cbSize;
1799
1800     // If this is non-null, pointer into LS for buffer.
1801     // LS can free this after the debug event is continued.
1802     BYTE  *m_pbLS; // @dbgtodo  cross-plat- for cross-platform purposes, this should be a TADDR
1803
1804     // If this is non-null, pointer into RS for buffer. RS must then free this. 
1805     // This buffer was copied from the LS (via CopyLSDataToRSWorker).
1806     BYTE  *m_pbRS;
1807 };
1808
1809 //-----------------------------------------------------------------------------
1810 // Byte wrapper around the buffer.
1811 //-----------------------------------------------------------------------------
1812 struct MSLAYOUT Ls_Rs_ByteBuffer : public Ls_Rs_BaseBuffer
1813 {
1814 #ifdef RIGHT_SIDE_COMPILE
1815     BYTE *GetRSPointer() 
1816     { 
1817         return m_pbRS;
1818     }
1819
1820     void CopyLSDataToRS(ICorDebugDataTarget * pTarget);
1821     BYTE *TransferRSData()
1822     {
1823         return TransferRSDataWorker();
1824     }
1825 #endif    
1826 };
1827
1828 //-----------------------------------------------------------------------------
1829 // Wrapper around a Ls_rS_Buffer to get it as a string.
1830 // This can also do some sanity checking.
1831 //-----------------------------------------------------------------------------
1832 struct MSLAYOUT Ls_Rs_StringBuffer : public Ls_Rs_BaseBuffer
1833 {
1834 #ifdef RIGHT_SIDE_COMPILE
1835     const WCHAR * GetString()
1836     {
1837         return reinterpret_cast<const WCHAR*> (m_pbRS);
1838     }
1839
1840     // Copy over the string.
1841     void CopyLSDataToRS(ICorDebugDataTarget * pTarget);
1842
1843     // Caller will pick up ownership.
1844     // Since caller will delete this data, we can't give back a constant pointer.
1845     WCHAR * TransferStringData()
1846     {
1847         return reinterpret_cast<WCHAR*> (TransferRSDataWorker());
1848     }
1849 #endif  
1850 };
1851
1852
1853 // Data for an Managed Debug Assistant Probe (MDA).
1854 struct MSLAYOUT DebuggerMDANotification
1855 {
1856     Ls_Rs_StringBuffer szName;
1857     Ls_Rs_StringBuffer szDescription;
1858     Ls_Rs_StringBuffer szXml;
1859     DWORD        dwOSThreadId;
1860     CorDebugMDAFlags flags;
1861 };
1862
1863
1864 // The only remaining problem is that register number mappings are different for each platform. It turns out
1865 // that the debugger only uses REGNUM_SP and REGNUM_AMBIENT_SP though, so we can just virtualize these two for
1866 // the target platform.
1867 // Keep this is sync with the definitions in inc/corinfo.h.
1868 #if defined(DBG_TARGET_X86)
1869 #define DBG_TARGET_REGNUM_SP 4
1870 #define DBG_TARGET_REGNUM_AMBIENT_SP 9
1871 #ifdef _TARGET_X86_
1872 static_assert_no_msg(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP);
1873 static_assert_no_msg(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP);
1874 #endif // _TARGET_X86_
1875 #elif defined(DBG_TARGET_AMD64)
1876 #define DBG_TARGET_REGNUM_SP 4
1877 #define DBG_TARGET_REGNUM_AMBIENT_SP 17
1878 #ifdef _TARGET_AMD64_
1879 static_assert_no_msg(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP);
1880 static_assert_no_msg(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP);
1881 #endif // _TARGET_AMD64_
1882 #elif defined(DBG_TARGET_ARM)
1883 #define DBG_TARGET_REGNUM_SP 13
1884 #define DBG_TARGET_REGNUM_AMBIENT_SP 17
1885 #ifdef _TARGET_ARM_
1886 C_ASSERT(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP);
1887 C_ASSERT(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP);
1888 #endif // _TARGET_ARM_
1889 #elif defined(DBG_TARGET_ARM64)
1890 #define DBG_TARGET_REGNUM_SP 31
1891 #define DBG_TARGET_REGNUM_AMBIENT_SP 34
1892 #ifdef _TARGET_ARM64_
1893 C_ASSERT(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP);
1894 C_ASSERT(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP);
1895 #endif // _TARGET_ARM64_
1896 #else
1897 #error Target registers are not defined for this platform
1898 #endif
1899
1900
1901 //
1902 // Event structure that is passed between the Runtime Controller and the
1903 // Debugger Interface. Some types of events are a fixed size and have
1904 // entries in the main union, while others are variable length and have
1905 // more specialized data structures that are attached to the end of this
1906 // structure.
1907 //
1908 struct MSLAYOUT DebuggerIPCEvent
1909 {
1910     DebuggerIPCEvent*       next;
1911     DebuggerIPCEventType    type;
1912     DWORD             processId;
1913     DWORD             threadId;
1914     VMPTR_AppDomain   vmAppDomain;
1915     VMPTR_Thread      vmThread;
1916
1917     HRESULT           hr;
1918     bool              replyRequired;
1919     bool              asyncSend;
1920
1921     union MSLAYOUT
1922     {
1923         struct MSLAYOUT
1924         {
1925             // Pointer to a BOOL in the target.
1926             CORDB_ADDRESS pfBeingDebugged;
1927         } LeftSideStartupData;
1928
1929         struct MSLAYOUT
1930         {
1931             // Module whos metadata is being updated
1932             // This tells the RS that the metadata for that module has become invalid.
1933             VMPTR_DomainFile vmDomainFile;
1934           
1935         } MetadataUpdateData;
1936
1937         struct MSLAYOUT
1938         {
1939             // Handle to CLR's internal appdomain object.
1940             VMPTR_AppDomain vmAppDomain;
1941         } AppDomainData;
1942
1943         struct MSLAYOUT
1944         {
1945             VMPTR_DomainAssembly vmDomainAssembly;
1946         } AssemblyData;
1947
1948 #ifdef TEST_DATA_CONSISTENCY
1949         // information necessary for testing whether the LS holds a lock on data
1950         // the RS needs to inspect. See code:DataTest::TestDataSafety and 
1951         // code:IDacDbiInterface::TestCrst for more information
1952         struct MSLAYOUT
1953         {
1954             // the lock to be tested
1955             VMPTR_Crst vmCrst;
1956             // indicates whether the LS holds the lock 
1957             bool       fOkToTake;
1958         } TestCrstData;
1959
1960         // information necessary for testing whether the LS holds a lock on data
1961         // the RS needs to inspect. See code:DataTest::TestDataSafety and 
1962         // code:IDacDbiInterface::TestCrst for more information
1963         struct MSLAYOUT
1964         {
1965             // the lock to be tested
1966             VMPTR_SimpleRWLock vmRWLock;
1967             // indicates whether the LS holds the lock  
1968             bool               fOkToTake;
1969         } TestRWLockData;
1970 #endif // TEST_DATA_CONSISTENCY
1971
1972         // Debug event that a module has been loaded
1973         struct MSLAYOUT
1974         {
1975             // Module that was just loaded.
1976             VMPTR_DomainFile vmDomainFile;
1977         }LoadModuleData;
1978
1979         
1980         struct MSLAYOUT
1981         {
1982             VMPTR_DomainFile vmDomainFile;
1983             LSPTR_ASSEMBLY debuggerAssemblyToken;
1984         } UnloadModuleData;
1985
1986         
1987         // The given module's pdb has been updated. 
1988         // Queury PDB from OOP
1989         struct MSLAYOUT
1990         {   
1991             VMPTR_DomainFile vmDomainFile;
1992         } UpdateModuleSymsData;
1993
1994         DebuggerMDANotification MDANotification;
1995
1996         struct MSLAYOUT
1997         {
1998             LSPTR_BREAKPOINT breakpointToken;
1999             mdMethodDef  funcMetadataToken;
2000             VMPTR_DomainFile vmDomainFile;
2001             bool         isIL;
2002             SIZE_T       offset;
2003             SIZE_T       encVersion;
2004             LSPTR_METHODDESC  nativeCodeMethodDescToken; // points to the MethodDesc if !isIL
2005         } BreakpointData;
2006
2007         struct MSLAYOUT
2008         {
2009             LSPTR_BREAKPOINT breakpointToken;
2010         } BreakpointSetErrorData;
2011
2012         struct MSLAYOUT
2013         {
2014             LSPTR_STEPPER        stepperToken;
2015             VMPTR_Thread         vmThreadToken;
2016             FramePointer         frameToken;
2017             bool                 stepIn;
2018             bool                 rangeIL;
2019             bool                 IsJMCStop;
2020             unsigned int         totalRangeCount;
2021             CorDebugStepReason   reason;
2022             CorDebugUnmappedStop rgfMappingStop;
2023             CorDebugIntercept    rgfInterceptStop;
2024             unsigned int         rangeCount;
2025             COR_DEBUG_STEP_RANGE range; //note that this is an array
2026         } StepData;
2027
2028         struct MSLAYOUT
2029         {
2030             // An unvalidated GC-handle
2031             VMPTR_OBJECTHANDLE GCHandle;
2032         } GetGCHandleInfo;
2033
2034         struct MSLAYOUT
2035         {
2036             // An unvalidated GC-handle for which we're returning the results
2037             LSPTR_OBJECTHANDLE GCHandle;
2038
2039             // The following are initialized by the LS in response to our query:
2040             VMPTR_AppDomain vmAppDomain; // AD that handle is in (only applicable if fValid).
2041             bool            fValid; // Did the LS determine the GC handle to be valid?
2042         } GetGCHandleInfoResult;
2043
2044         // Allocate memory on the left-side
2045         struct MSLAYOUT
2046         {
2047             ULONG      bufSize;             // number of bytes to allocate
2048         } GetBuffer;
2049
2050         // Memory allocated on the left-side
2051         struct MSLAYOUT
2052         {
2053             void        *pBuffer;           // LS pointer to the buffer allocated
2054             HRESULT     hr;                 // success / failure
2055         } GetBufferResult;
2056
2057         // Free a buffer allocated on the left-side with GetBuffer
2058         struct MSLAYOUT
2059         {
2060             void        *pBuffer;           // Pointer previously returned in GetBufferResult
2061         } ReleaseBuffer;
2062
2063         struct MSLAYOUT
2064         {
2065             HRESULT     hr;
2066         } ReleaseBufferResult;
2067
2068         // Apply an EnC edit
2069         struct MSLAYOUT
2070         {            
2071             VMPTR_DomainFile vmDomainFile;      // Module to edit
2072             DWORD cbDeltaMetadata;              // size of blob pointed to by pDeltaMetadata
2073             CORDB_ADDRESS pDeltaMetadata;       // pointer to delta metadata in debuggee
2074                                                 // it's the RS's responsibility to allocate and free
2075                                                 // this (and pDeltaIL) using GetBuffer / ReleaseBuffer
2076             CORDB_ADDRESS pDeltaIL;             // pointer to delta IL in debugee
2077             DWORD cbDeltaIL;                    // size of blob pointed to by pDeltaIL
2078         } ApplyChanges;
2079
2080         struct MSLAYOUT
2081         {
2082             HRESULT hr;
2083         } ApplyChangesResult;
2084
2085         struct MSLAYOUT
2086         {
2087             mdTypeDef   classMetadataToken;
2088             VMPTR_DomainFile vmDomainFile;
2089             LSPTR_ASSEMBLY classDebuggerAssemblyToken;
2090         } LoadClass;
2091
2092         struct MSLAYOUT
2093         {
2094             mdTypeDef   classMetadataToken;
2095             VMPTR_DomainFile vmDomainFile;
2096             LSPTR_ASSEMBLY classDebuggerAssemblyToken;
2097         } UnloadClass;
2098
2099         struct MSLAYOUT
2100         {            
2101             VMPTR_DomainFile vmDomainFile;
2102             bool  flag;
2103         } SetClassLoad;
2104
2105         struct MSLAYOUT
2106         {
2107             VMPTR_OBJECTHANDLE vmExceptionHandle;
2108             bool        firstChance;
2109             bool        continuable;
2110         } Exception;
2111
2112         struct MSLAYOUT
2113         {
2114             VMPTR_Thread   vmThreadToken;
2115         } ClearException;
2116
2117         struct MSLAYOUT
2118         {
2119             void        *address;
2120         } IsTransitionStub;
2121
2122         struct MSLAYOUT
2123         {
2124             bool        isStub;
2125         } IsTransitionStubResult;
2126
2127         struct MSLAYOUT
2128         {
2129             CORDB_ADDRESS    startAddress;
2130             bool             fCanSetIPOnly;
2131             VMPTR_Thread     vmThreadToken;
2132             VMPTR_DomainFile vmDomainFile;
2133             mdMethodDef      mdMethod;
2134             VMPTR_MethodDesc vmMethodDesc;
2135             SIZE_T           offset;
2136             bool             fIsIL;
2137             void *           firstExceptionHandler;
2138         } SetIP; // this is also used for CanSetIP
2139
2140         struct MSLAYOUT
2141         {
2142             int iLevel;
2143
2144             EmbeddedIPCString<MAX_LOG_SWITCH_NAME_LEN + 1> szCategory;
2145             Ls_Rs_StringBuffer szContent;
2146         } FirstLogMessage;
2147
2148         struct MSLAYOUT
2149         {
2150             int iLevel;
2151             int iReason;
2152
2153             EmbeddedIPCString<MAX_LOG_SWITCH_NAME_LEN + 1> szSwitchName;
2154             EmbeddedIPCString<MAX_LOG_SWITCH_NAME_LEN + 1> szParentSwitchName;
2155         } LogSwitchSettingMessage;
2156
2157         // information needed to send to the RS as part of a custom notification from the target
2158         struct MSLAYOUT
2159         {
2160             // Domain file for the domain in which the notification occurred
2161             VMPTR_DomainFile vmDomainFile;
2162
2163             // metadata token for the type of the CustomNotification object's type
2164             mdTypeDef    classToken;
2165         } CustomNotification;
2166
2167         struct MSLAYOUT
2168         {
2169             VMPTR_Thread vmThreadToken;
2170             CorDebugThreadState debugState;
2171         } SetAllDebugState;
2172
2173         DebuggerIPCE_FuncEvalInfo FuncEval;
2174
2175         struct MSLAYOUT
2176         {
2177             CORDB_ADDRESS argDataArea;
2178             LSPTR_DEBUGGEREVAL debuggerEvalKey;
2179         } FuncEvalSetupComplete;
2180
2181         struct MSLAYOUT
2182         {
2183             RSPTR_CORDBEVAL funcEvalKey;
2184             bool            successful;
2185             bool            aborted;
2186             void           *resultAddr;
2187
2188             // AppDomain that the result is in.
2189             VMPTR_AppDomain vmAppDomain;
2190
2191             VMPTR_OBJECTHANDLE vmObjectHandle;
2192             DebuggerIPCE_ExpandedTypeData resultType;
2193         } FuncEvalComplete;
2194
2195         struct MSLAYOUT
2196         {
2197             LSPTR_DEBUGGEREVAL debuggerEvalKey;
2198         } FuncEvalAbort;
2199
2200         struct MSLAYOUT
2201         {
2202             LSPTR_DEBUGGEREVAL debuggerEvalKey;
2203         } FuncEvalRudeAbort;
2204
2205         struct MSLAYOUT
2206         {
2207             LSPTR_DEBUGGEREVAL debuggerEvalKey;
2208         } FuncEvalCleanup;
2209
2210         struct MSLAYOUT
2211         {
2212             void           *objectRefAddress;
2213             VMPTR_OBJECTHANDLE vmObjectHandle;
2214             void           *newReference;
2215         } SetReference;
2216
2217         struct MSLAYOUT
2218         {
2219             NameChangeType  eventType;
2220             VMPTR_AppDomain vmAppDomain;
2221             VMPTR_Thread    vmThread;
2222         } NameChange;
2223
2224         struct MSLAYOUT
2225         {
2226             VMPTR_DomainFile vmDomainFile;
2227             BOOL             fAllowJitOpts;
2228             BOOL             fEnableEnC;
2229         } JitDebugInfo;
2230
2231         // EnC Remap opportunity
2232         struct MSLAYOUT
2233         {
2234             VMPTR_DomainFile vmDomainFile;
2235             mdMethodDef funcMetadataToken ;        // methodDef of function with remap opportunity
2236             SIZE_T          currentVersionNumber;  // version currently executing
2237             SIZE_T          resumeVersionNumber;   // latest version
2238             SIZE_T          currentILOffset;       // the IL offset of the current IP
2239             SIZE_T          *resumeILOffset;       // pointer into left-side where an offset to resume
2240                                                    // to should be written if remap is desired.
2241         } EnCRemap;
2242
2243         // EnC Remap has taken place
2244         struct MSLAYOUT
2245         {
2246             VMPTR_DomainFile vmDomainFile;
2247             mdMethodDef funcMetadataToken;         // methodDef of function that was remapped
2248         } EnCRemapComplete;
2249
2250         // Notification that the LS is about to update a CLR data structure to account for a
2251         // specific edit made by EnC (function add/update or field add).
2252         struct MSLAYOUT
2253         {
2254             VMPTR_DomainFile vmDomainFile;
2255             mdToken         memberMetadataToken;   // Either a methodDef token indicating the function that
2256                                                    // was updated/added, or a fieldDef token indicating the
2257                                                    // field which was added.
2258             mdTypeDef       classMetadataToken;    // TypeDef token of the class in which the update was made
2259             SIZE_T          newVersionNumber;      // The new function/module version
2260         } EnCUpdate;
2261
2262         struct MSLAYOUT
2263         {
2264             void      *oldData;
2265             void      *newData;
2266             DebuggerIPCE_BasicTypeData type;
2267         } SetValueClass;
2268
2269
2270         // Event used to tell LS if a single function is user or non-user code.
2271         // Same structure used to get function status.
2272         // @todo - Perhaps we can bundle these up so we can set multiple funcs w/ 1 event?
2273         struct MSLAYOUT
2274         {
2275             VMPTR_DomainFile vmDomainFile;
2276             mdMethodDef     funcMetadataToken;
2277             DWORD           dwStatus;
2278         } SetJMCFunctionStatus;
2279
2280         struct MSLAYOUT
2281         {
2282             TASKID      taskid;
2283         } GetThreadForTaskId;
2284
2285         struct MSLAYOUT
2286         {
2287             VMPTR_Thread vmThreadToken;
2288         } GetThreadForTaskIdResult;
2289
2290         struct MSLAYOUT
2291         {
2292             CONNID     connectionId;
2293         } ConnectionChange;
2294
2295         struct MSLAYOUT
2296         {
2297             CONNID     connectionId;
2298             EmbeddedIPCString<MAX_LONGPATH> wzConnectionName;
2299         } CreateConnection;
2300
2301         struct MSLAYOUT
2302         {
2303             void            *objectToken;
2304             BOOL          fStrong;
2305         } CreateHandle;
2306
2307         struct MSLAYOUT
2308         {
2309             VMPTR_OBJECTHANDLE vmObjectHandle;
2310         } CreateHandleResult;
2311
2312         // used in DB_IPCE_DISPOSE_HANDLE event
2313         struct MSLAYOUT
2314         {
2315             VMPTR_OBJECTHANDLE vmObjectHandle;
2316             BOOL            fStrong;
2317         } DisposeHandle;
2318
2319         struct MSLAYOUT
2320         {
2321             FramePointer                  framePointer;
2322             SIZE_T                        nOffset;
2323             CorDebugExceptionCallbackType eventType;
2324             DWORD                         dwFlags;
2325             VMPTR_OBJECTHANDLE            vmExceptionHandle;
2326         } ExceptionCallback2;
2327
2328         struct MSLAYOUT
2329         {
2330             CorDebugExceptionUnwindCallbackType eventType;
2331             DWORD                               dwFlags;
2332         } ExceptionUnwind;
2333
2334         struct MSLAYOUT
2335         {
2336             VMPTR_Thread vmThreadToken;
2337             FramePointer frameToken;
2338         } InterceptException;
2339
2340         struct MSLAYOUT
2341         {
2342             VMPTR_Module vmModule;
2343             void * pMetadataStart;
2344             ULONG nMetadataSize;
2345         } MetadataUpdateRequest;
2346
2347     };
2348 };
2349
2350
2351 // When using a network transport rather than shared memory buffers CorDBIPC_BUFFER_SIZE is the upper bound
2352 // for a single DebuggerIPCEvent structure. This now relates to the maximal size of a network message and is
2353 // orthogonal to the host's page size. Round the buffer size up to a multiple of 8 since MSVC seems more
2354 // aggressive in this regard than gcc.
2355 #define CorDBIPC_TRANSPORT_BUFFER_SIZE (((sizeof(DebuggerIPCEvent) + 7) / 8) * 8)
2356
2357 // A DebuggerIPCEvent must fit in the send & receive buffers, which are CorDBIPC_BUFFER_SIZE bytes.
2358 static_assert_no_msg(sizeof(DebuggerIPCEvent) <= CorDBIPC_BUFFER_SIZE);
2359 static_assert_no_msg(CorDBIPC_TRANSPORT_BUFFER_SIZE <= CorDBIPC_BUFFER_SIZE);
2360
2361 // 2*sizeof(WCHAR) for the two string terminating characters in the FirstLogMessage
2362 #define LOG_MSG_PADDING         4
2363
2364 #endif /* _DbgIPCEvents_h_ */