Deal with cross-bitness compilation warnings Pt.2 (#19781)
[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 (2096)
184 #else
185 #define CorDBIPC_BUFFER_SIZE (2088) // hand tuned to ensure that ipc block in IPCHeader.h fits in 1 page.
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\process.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) +
191                                   //                              other fields = page size)
192 #endif // DBG_TARGET_X86 || DBG_TARGET_ARM
193
194 //
195 // DebuggerIPCControlBlock describes the layout of the shared memory shared between the Left Side and the Right
196 // Side. This includes error information, handles for the IPC channel, and space for the send/receive buffers.
197 //
198 struct MSLAYOUT DebuggerIPCControlBlock
199 {
200     // Version data should be first in the control block to ensure that we can read it even if the control block
201     // changes.
202     SIZE_T                     m_DCBSize;           // note this field is used as a semaphore to indicate the DCB is initialized
203     ULONG                      m_verMajor;          // CLR build number for the Left Side.
204     ULONG                      m_verMinor;          // CLR build number for the Left Side.
205
206     // This next stuff fits in a  DWORD.
207     bool                       m_checkedBuild;      // CLR build type for the Left Side.
208     // using the first padding byte to indicate if hosted in fiber mode.
209     // We actually just need one bit. So if needed, can turn this to a bit.
210     // BYTE padding1;
211     bool                       m_bHostingInFiber;
212     BYTE padding2;
213     BYTE padding3;
214
215     ULONG                      m_leftSideProtocolCurrent;       // Current protocol version for the Left Side.
216     ULONG                      m_leftSideProtocolMinSupported;  // Minimum protocol the Left Side can support.
217
218     ULONG                      m_rightSideProtocolCurrent;      // Current protocol version for the Right Side.
219     ULONG                      m_rightSideProtocolMinSupported; // Minimum protocol the Right Side requires.
220
221     HRESULT                    m_errorHR;
222     unsigned int               m_errorCode;
223
224 #if defined(DBG_TARGET_WIN64)
225     // 64-bit needs this padding to make the handles after this aligned.
226     // But x86 can't have this padding b/c it breaks binary compatibility between v1.1 and v2.0.
227     ULONG padding4;
228 #endif // DBG_TARGET_WIN64
229
230
231     RemoteHANDLE               m_rightSideEventAvailable;
232     RemoteHANDLE               m_rightSideEventRead;
233
234     // @dbgtodo  inspection - this is where LSEA and LSER used to be. We need to the padding to maintain binary compatibility.
235     // Eventually, we expect to remove this whole block.
236     RemoteHANDLE               m_paddingObsoleteLSEA;
237     RemoteHANDLE               m_paddingObsoleteLSER;
238
239     RemoteHANDLE               m_rightSideProcessHandle;
240
241     //.............................................................................
242     // Everything above this point must have the exact same binary layout as v1.1.
243     // See protocol details below.
244     //.............................................................................
245
246     RemoteHANDLE               m_leftSideUnmanagedWaitEvent;
247     
248
249
250     // This is set immediately when the helper thread is created.
251     // This will be set even if there's a temporary helper thread or if the real helper
252     // thread is not yet pumping (eg, blocked on a loader lock).
253     DWORD                      m_realHelperThreadId;
254
255     // This is only published once the helper thread starts running in its main loop.
256     // Thus we can use this field to see if the real helper thread is actually pumping.
257     DWORD                      m_helperThreadId;
258
259     // This is non-zero if the LS has a temporary helper thread.
260     DWORD                      m_temporaryHelperThreadId;
261
262     // ID of the Helper's canary thread.
263     DWORD                      m_CanaryThreadId;
264
265     DebuggerIPCRuntimeOffsets *m_pRuntimeOffsets;
266     void                      *m_helperThreadStartAddr;
267     void                      *m_helperRemoteStartAddr;
268     DWORD                     *m_specialThreadList;
269
270     BYTE                       m_receiveBuffer[CorDBIPC_BUFFER_SIZE];
271     BYTE                       m_sendBuffer[CorDBIPC_BUFFER_SIZE];
272
273     DWORD                      m_specialThreadListLength;
274     bool                       m_shutdownBegun;
275     bool                       m_rightSideIsWin32Debugger;  // RS status
276     bool                       m_specialThreadListDirty;
277
278     bool                       m_rightSideShouldCreateHelperThread;
279
280     // NOTE The Init method works since there are no virtual functions - don't add any virtual functions without
281     // changing this!
282     // Only initialized by the LS, opened by the RS.
283     HRESULT Init(
284                  HANDLE rsea, 
285                  HANDLE rser, 
286                  HANDLE lsea, 
287                  HANDLE lser,
288                  HANDLE lsuwe
289                 );
290
291 };
292
293 #if defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
294
295 // We need an alternate definition for the control block if using the transport, because the control block has to be sent over the transport
296 // In particular we can't nest the send/receive buffers inside of it and we don't use any of the remote handles
297
298 struct MSLAYOUT DebuggerIPCControlBlockTransport
299 {
300     // Version data should be first in the control block to ensure that we can read it even if the control block
301     // changes.
302     SIZE_T                     m_DCBSize;           // note this field is used as a semaphore to indicate the DCB is initialized
303     ULONG                      m_verMajor;          // CLR build number for the Left Side.
304     ULONG                      m_verMinor;          // CLR build number for the Left Side.
305
306     // This next stuff fits in a  DWORD.
307     bool                       m_checkedBuild;      // CLR build type for the Left Side.
308     // using the first padding byte to indicate if hosted in fiber mode.
309     // We actually just need one bit. So if needed, can turn this to a bit.
310     // BYTE padding1;
311     bool                       m_bHostingInFiber;
312     BYTE padding2;
313     BYTE padding3;
314
315     ULONG                      m_leftSideProtocolCurrent;       // Current protocol version for the Left Side.
316     ULONG                      m_leftSideProtocolMinSupported;  // Minimum protocol the Left Side can support.
317
318     ULONG                      m_rightSideProtocolCurrent;      // Current protocol version for the Right Side.
319     ULONG                      m_rightSideProtocolMinSupported; // Minimum protocol the Right Side requires.
320
321     HRESULT                    m_errorHR;
322     unsigned int               m_errorCode;
323
324 #if defined(DBG_TARGET_WIN64)
325     // 64-bit needs this padding to make the handles after this aligned.
326     // But x86 can't have this padding b/c it breaks binary compatibility between v1.1 and v2.0.
327     ULONG padding4;
328 #endif // DBG_TARGET_WIN64
329
330     // This is set immediately when the helper thread is created.
331     // This will be set even if there's a temporary helper thread or if the real helper
332     // thread is not yet pumping (eg, blocked on a loader lock).
333     DWORD                      m_realHelperThreadId;
334
335     // This is only published once the helper thread starts running in its main loop.
336     // Thus we can use this field to see if the real helper thread is actually pumping.
337     DWORD                      m_helperThreadId;
338
339     // This is non-zero if the LS has a temporary helper thread.
340     DWORD                      m_temporaryHelperThreadId;
341
342     // ID of the Helper's canary thread.
343     DWORD                      m_CanaryThreadId;
344
345     DebuggerIPCRuntimeOffsets *m_pRuntimeOffsets;
346     void                      *m_helperThreadStartAddr;
347     void                      *m_helperRemoteStartAddr;
348     DWORD                     *m_specialThreadList;
349
350     DWORD                      m_specialThreadListLength;
351     bool                       m_shutdownBegun;
352     bool                       m_rightSideIsWin32Debugger;  // RS status
353     bool                       m_specialThreadListDirty;
354
355     bool                       m_rightSideShouldCreateHelperThread;
356
357     // NOTE The Init method works since there are no virtual functions - don't add any virtual functions without
358     // changing this!
359     // Only initialized by the LS, opened by the RS.
360     HRESULT Init();
361
362 };
363
364 #endif // defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
365
366 #if defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
367 #include "dbgtransportsession.h"
368 #endif // defined(FEATURE_DBGIPC_TRANSPORT_VM) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
369
370 #if defined(DBG_TARGET_X86) && !defined(FEATURE_CORESYSTEM)
371 // We have an versioning requirement.
372 // 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
373 // to look at a v2.0 app enough to recognize the version mismatch.
374 // This check is only necessary for platforms that ran on v1.1 (Win32-x86)
375
376 // Just to catch any potential illegal change in the IPC block, we assert the offsets against the offsets from v1.1.
377 // The constants here are pulled from v1.1.
378 // The RS will look at these versioning fields, so they absolutely must line up.
379 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_leftSideProtocolCurrent) == 0x10);
380 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_leftSideProtocolMinSupported) == 0x14);
381 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProtocolCurrent) == 0x18);
382 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProtocolMinSupported) == 0x1c);
383
384 // Unfortunately, on detecting such failure, v1.1 will also null out LSEA, LSER and RSPH.
385 // If these get adjusted, a version-mismatch attach  will effectively null out random fields.
386 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_paddingObsoleteLSEA) == 0x30);
387 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_paddingObsoleteLSER) == 0x34);
388 static_assert_no_msg(offsetof(DebuggerIPCControlBlock, m_rightSideProcessHandle) == 0x38);
389
390
391
392 #endif
393
394 #define INITIAL_APP_DOMAIN_INFO_LIST_SIZE   16
395
396
397 //-----------------------------------------------------------------------------
398 // Provide some Type-safety in the IPC block when we pass remote pointers around.
399 //-----------------------------------------------------------------------------
400
401
402 //-----------------------------------------------------------------------------
403 // This is the same in both the LS & RS.
404 // Definitions on the LS & RS should be binary compatible. So all storage is
405 // declared in GeneralLsPointer, and then the Ls & RS each have their own
406 // derived accessors.
407 //-----------------------------------------------------------------------------
408 class MSLAYOUT GeneralLsPointer
409 {
410 protected:
411     friend ULONG_PTR LsPtrToCookie(GeneralLsPointer p);
412     void * m_ptr;
413
414 public:
415     bool IsNull() { return m_ptr == NULL; }
416 };
417
418 class MSLAYOUT GeneralRsPointer
419 {
420 protected:
421     UINT m_data;
422
423 public:
424     bool IsNull() { return m_data == 0; }
425 };
426
427 // In some cases, we need to get a uuid from a pointer (ie, in a hash)
428 inline ULONG_PTR LsPtrToCookie(GeneralLsPointer p) {
429     return (ULONG_PTR) p.m_ptr;
430 }
431 #define VmPtrToCookie(vm) LsPtrToCookie((vm).ToLsPtr())
432
433
434 #ifdef RIGHT_SIDE_COMPILE
435 //-----------------------------------------------------------------------------
436 // Infrasturcture for RS Definitions
437 //-----------------------------------------------------------------------------
438
439 // On the RS, we don't have the LS classes defined, so we can't templatize that
440 // in terms of <class T>, but we still want things to be unique.
441 // So we create an empty enum for each LS type and then templatize it in terms
442 // of the enum.
443 template <typename T>
444 class MSLAYOUT LsPointer : public GeneralLsPointer
445 {
446 public:
447     void Set(void * p)
448     {
449         m_ptr = p;
450     }
451     void * UnsafeGet()
452     {
453         return m_ptr;
454     }
455
456     static LsPointer<T> NullPtr()
457     {
458         return MakePtr(NULL);
459     }
460
461     static LsPointer<T> MakePtr(T* p)
462     {
463 #ifdef _PREFAST_
464 #pragma warning(push)
465 #pragma warning(disable:6001) // PREfast warning: Using uninitialize memory 't'
466 #endif // _PREFAST_
467
468         LsPointer<T> t;
469         t.Set(p);
470         return t;
471
472 #ifdef _PREFAST_
473 #pragma warning(pop)
474 #endif // _PREFAST_
475     }
476
477     bool operator!= (void * p) { return m_ptr != p; }
478     bool operator== (void * p) { return m_ptr == p; }
479     bool operator==(LsPointer<T> p) { return p.m_ptr == this->m_ptr; }
480
481     // We should never UnWrap() them in the RS, so we don't define that here.
482 };
483
484 class CordbProcess;
485 template <class T> UINT AllocCookie(CordbProcess * pProc, T * p);
486 template <class T> T * UnwrapCookie(CordbProcess * pProc, UINT cookie);
487
488 UINT AllocCookieCordbEval(CordbProcess * pProc, class CordbEval * p);
489 class CordbEval * UnwrapCookieCordbEval(CordbProcess * pProc, UINT cookie);
490
491 template <class CordbEval> UINT AllocCookie(CordbProcess * pProc, CordbEval * p)
492 {
493     return AllocCookieCordbEval(pProc, p);
494 }
495 template <class CordbEval> CordbEval * UnwrapCookie(CordbProcess * pProc, UINT cookie)
496 {
497     return UnwrapCookieCordbEval(pProc, cookie);
498 }
499
500
501
502 // This is how the RS sees the pointers in the IPC block.
503 template<class T>
504 class MSLAYOUT RsPointer : public GeneralRsPointer
505 {
506 public:
507     // Since we're being used inside a union, we can't have a ctor.
508
509     static RsPointer<T> NullPtr()
510     {
511         RsPointer<T> t;
512         t.m_data = 0;
513         return t;        
514     }
515
516     bool AllocHandle(CordbProcess *pProc, T* p)
517     {    
518         // This will force validation.
519         m_data = AllocCookie<T>(pProc, p);
520         return (m_data != 0);       
521     }
522
523     bool operator==(RsPointer<T> p) { return p.m_data == this->m_data; }
524
525     T* UnWrapAndRemove(CordbProcess *pProc)
526     {
527         return UnwrapCookie<T>(pProc, m_data);
528     }
529     
530 protected:
531 };
532
533 // Forward declare a class so that each type of LS pointer can have
534 // its own type.  We use the real class name to be compatible with VMPTRs.
535 #define DEFINE_LSPTR_TYPE(ls_type, ptr_name) \
536     ls_type; \
537     typedef LsPointer<ls_type> ptr_name;
538
539
540 #define DEFINE_RSPTR_TYPE(rs_type, ptr_name) \
541     class rs_type; \
542     typedef RsPointer<rs_type> ptr_name;
543
544 #else // !RIGHT_SIDE_COMPILE
545 //-----------------------------------------------------------------------------
546 // Infrastructure for LS Definitions
547 //-----------------------------------------------------------------------------
548
549 // This is how the LS sees the pointers in the IPC block.
550 template<typename T>
551 class MSLAYOUT LsPointer : public GeneralLsPointer
552 {
553 public:
554     // Since we're being used inside a union, we can't have a ctor.
555     //LsPointer() { }
556
557     static LsPointer<T> NullPtr()
558     {
559         return MakePtr(NULL);
560     }
561
562     static LsPointer<T> MakePtr(T * p)
563     {
564 #ifdef _PREFAST_
565 #pragma warning(push)
566 #pragma warning(disable:6001) // PREfast warning: Using uninitialize memory 't'
567 #endif // _PREFAST_
568
569         LsPointer<T> t;
570         t.Set(p);
571         return t;
572
573 #ifdef _PREFAST_
574 #pragma warning(pop)
575 #endif // _PREFAST_
576     }
577
578     bool operator!= (void * p) { return m_ptr != p; }
579     bool operator== (void * p) { return m_ptr == p; }
580     bool operator==(LsPointer<T> p) { return p.m_ptr == this->m_ptr; }
581
582     // @todo - we want to be able to swap out Set + Unwrap functions
583     void Set(T * p)
584     {
585         SUPPORTS_DAC;
586         // We could validate the pointer here.
587         m_ptr = p;
588     }
589
590     T * UnWrap()
591     {
592         // If we wanted to validate the pointer, here's our chance.
593         return static_cast<T*>(m_ptr);        
594     }
595 };
596
597 template <class n>
598 class MSLAYOUT RsPointer : public GeneralRsPointer
599 {
600 public:
601     static RsPointer<n> NullPtr()
602     {
603         RsPointer<n> t;
604         t.m_data = 0;
605         return t;
606     }
607
608     bool operator==(RsPointer<n> p) { return p.m_data == this->m_data; }
609
610     // We should never UnWrap() them in the LS, so we don't define that here.
611 };
612
613 #define DEFINE_LSPTR_TYPE(ls_type, ptr_name) \
614     ls_type; \
615     typedef LsPointer<ls_type> ptr_name;
616
617 #define DEFINE_RSPTR_TYPE(rs_type, ptr_name) \
618     enum __RS__##rs_type { };  \
619     typedef RsPointer<__RS__##rs_type> ptr_name;
620
621 #endif // !RIGHT_SIDE_COMPILE
622
623 // We must be binary compatible w/ a pointer.
624 static_assert_no_msg(sizeof(LsPointer<void>) == sizeof(GeneralLsPointer));
625
626 static_assert_no_msg(sizeof(void*) == sizeof(GeneralLsPointer));
627
628
629
630 //-----------------------------------------------------------------------------
631 // Definitions for Left-Side ptrs.
632 // NOTE: Use VMPTR instead of LSPTR. Don't add new LSPTR types.
633 // 
634 //-----------------------------------------------------------------------------
635
636
637
638 DEFINE_LSPTR_TYPE(class Assembly,  LSPTR_ASSEMBLY);
639 DEFINE_LSPTR_TYPE(class DebuggerJitInfo, LSPTR_DJI);
640 DEFINE_LSPTR_TYPE(class DebuggerMethodInfo, LSPTR_DMI);
641 DEFINE_LSPTR_TYPE(class MethodDesc,         LSPTR_METHODDESC);
642 DEFINE_LSPTR_TYPE(class DebuggerBreakpoint, LSPTR_BREAKPOINT);
643 DEFINE_LSPTR_TYPE(class DebuggerEval,       LSPTR_DEBUGGEREVAL);
644 DEFINE_LSPTR_TYPE(class DebuggerStepper,    LSPTR_STEPPER);
645
646 // Need to be careful not to annoy the compiler here since DT_CONTEXT is a typedef, not a struct.
647 #if defined(RIGHT_SIDE_COMPILE)
648 typedef LsPointer<DT_CONTEXT> LSPTR_CONTEXT;
649 #else  // RIGHT_SIDE_COMPILE
650 typedef LsPointer<DT_CONTEXT> LSPTR_CONTEXT;
651 #endif // RIGHT_SIDE_COMPILE
652
653 DEFINE_LSPTR_TYPE(struct OBJECTHANDLE__,    LSPTR_OBJECTHANDLE);
654 DEFINE_LSPTR_TYPE(class TypeHandleDummyPtr, LSPTR_TYPEHANDLE); // TypeHandle in the LS is not a direct pointer.
655
656 //-----------------------------------------------------------------------------
657 // Definitions for Right-Side ptrs.
658 //-----------------------------------------------------------------------------
659 DEFINE_RSPTR_TYPE(CordbEval,               RSPTR_CORDBEVAL);
660
661
662 //---------------------------------------------------------------------------------------
663 // VMPTR_Base is the base type for an abstraction over pointers into the VM so 
664 // that DBI can treat them as opaque handles. Classes will derive from it to 
665 // provide type-safe Target pointers, which ICD will view as opaque handles.
666 //
667 // Lifetimes:  
668 //   VMPTR_ objects survive across flushing the DAC cache. Therefore, the underlying
669 //   storage must be a target-pointer (and not a marshalled host pointer).
670 //   The RS must ensure they're still in sync with the LS (eg, by
671 //   tracking unload events).
672 //  
673 //
674 // Assumptions:
675 //    These handles are TADDR pointers and must not require any cleanup from DAC/DBI.
676 //    For direct untyped pointers into the VM, use CORDB_ADDRESS.
677 //
678 // Notes:
679 //  1. This helps enforce that DBI goes through the primitives interface
680 //     for all access (and that it doesn't accidentally start calling
681 //     dac-ized methods on the objects)
682 //  2. This isolates DBI from VM headers. 
683 //  3. This isolates DBI from the dac implementation (of DAC_Ptr)
684 //  4. This is distinct from LSPTR because LSPTRs are truly opaque handles, whereas VMPtrs
685 //     move across VM, DAC, and DBI, exposing proper functionality in each component.
686 //  5. VMPTRs are blittable because they are Target Addresses which act as opaque
687 //     handles outside of the Target / Dac-marshaller.  
688 //
689 //---------------------------------------------------------------------------------------
690
691
692 template <typename TTargetPtr, typename TDacPtr>
693 class MSLAYOUT VMPTR_Base
694 {
695     // Underlying pointer into Target address space.
696     // Target pointers are blittable. 
697     // - In Target: can be used as normal local pointers.
698     // - In DAC: must be marshalled to a host-pointer and then they can be used via DAC
699     // - In RS: opaque handles.
700 private:
701     TADDR m_addr;
702
703 public:
704     typedef VMPTR_Base<TTargetPtr,TDacPtr> VMPTR_This;
705
706     // For DBI, VMPTRs are opaque handles.
707     // But the DAC side is allowed to inspect the handles to get at the raw pointer.
708 #if defined(ALLOW_VMPTR_ACCESS)
709     // 
710     // Case 1: Using in DAcDbi implementation
711     //
712
713     // DAC accessor
714     TDacPtr GetDacPtr() const
715     {
716         SUPPORTS_DAC;
717         return TDacPtr(m_addr);
718     }
719
720
721     // This will initialize the handle to a given target-pointer. 
722     // We choose TADDR to make it explicit that it's a target pointer and avoid the risk
723     // of it accidentally getting marshalled to a host pointer. 
724     void SetDacTargetPtr(TADDR addr)
725     {
726         SUPPORTS_DAC;
727         m_addr = addr;
728     }
729     
730     void SetHostPtr(const TTargetPtr * pObject)
731     {
732         SUPPORTS_DAC;
733         m_addr = PTR_HOST_TO_TADDR(pObject);        
734     }
735
736
737 #elif !defined(RIGHT_SIDE_COMPILE)
738     //
739     // Case 2: Used in Left-side. Can get/set from local pointers.
740     //
741
742     // This will set initialize from a Target pointer. Since this is happening in the 
743     // Left-side (Target), the pointer is local.
744     // This is commonly used by the Left-side to create a VMPTR_ for a notification event.
745     void SetRawPtr(TTargetPtr * ptr) 
746     {
747         m_addr = reinterpret_cast<TADDR>(ptr);
748     }
749
750     // This will get the raw underlying target pointer. 
751     // This can be used by inproc Left-side code to unwrap a VMPTR (Eg, for a func-eval
752     // hijack or in-proc worker threads)
753     TTargetPtr * GetRawPtr()
754     {
755         return reinterpret_cast<TTargetPtr*>(m_addr);
756     }
757
758     // Convenience for converting TTargetPtr --> VMPTR
759     static VMPTR_This MakePtr(TTargetPtr * ptr)
760     {
761 #ifdef _PREFAST_
762 #pragma warning(push)
763 #pragma warning(disable:6001) // PREfast warning: Using uninitialize memory 't'
764 #endif // _PREFAST_
765
766         VMPTR_This t;
767         t.SetRawPtr(ptr);
768         return t;
769
770 #ifdef _PREFAST_
771 #pragma warning(pop)
772 #endif // _PREFAST_
773     }
774
775
776 #else
777     //
778     // Case 3: Used in RS. Opaque handles only.
779     //
780 #endif
781
782
783 #ifndef DACCESS_COMPILE
784     // For compatibility, these can be converted to LSPTRs on the RS or LS (case 2 and 3).  We don't allow
785     // this in the DAC case because it's a cast between address spaces which we're trying to eliminate
786     // in the DAC code.
787     // @dbgtodo  inspection: LSPTRs will go away entirely once we've moved completely over to DAC
788     LsPointer<TTargetPtr> ToLsPtr()
789     {
790         return LsPointer<TTargetPtr>::MakePtr( reinterpret_cast<TTargetPtr *>(m_addr));
791     }
792 #endif
793     
794     //
795     // Operators to emulate Pointer semantics.
796     //
797     bool IsNull() { SUPPORTS_DAC; return m_addr == NULL; }
798
799     static VMPTR_This NullPtr()
800     {
801         SUPPORTS_DAC;
802
803 #ifdef _PREFAST_
804 #pragma warning(push)
805 #pragma warning(disable:6001) // PREfast warning: Using uninitialize memory 't'
806 #endif // _PREFAST_
807
808         VMPTR_This dummy;
809         dummy.m_addr = NULL;
810         return dummy;
811
812 #ifdef _PREFAST_
813 #pragma warning(pop)
814 #endif // _PREFAST_
815     }
816
817     bool operator!= (VMPTR_This vmOther) const { SUPPORTS_DAC; return this->m_addr != vmOther.m_addr; }
818     bool operator== (VMPTR_This vmOther) const { SUPPORTS_DAC; return this->m_addr == vmOther.m_addr; }
819 };
820
821 #if defined(ALLOW_VMPTR_ACCESS)
822 // Helper macro to define a VMPTR.
823 // This is used in the DAC case, so this definition connects the pointers up to their DAC values.
824 #define DEFINE_VMPTR(ls_type, dac_ptr_type, ptr_name) \
825     ls_type;  \
826     typedef VMPTR_Base<ls_type, dac_ptr_type> ptr_name;
827
828 #else
829 // Helper macro to define a VMPTR.
830 // This is used in the Right-side and Left-side (but not DAC) case.
831 // This definition explicitly ignores dac_ptr_type to prevent accidental DAC usage.
832 #define DEFINE_VMPTR(ls_type, dac_ptr_type, ptr_name) \
833     ls_type;  \
834     typedef VMPTR_Base<ls_type, void> ptr_name;
835
836 #endif
837
838 // Declare VMPTRs.
839 // The naming convention for instantiating a VMPTR is a 'vm' prefix. 
840 //
841 //           VM definition,         DAC definition,     pretty name for VMPTR
842 DEFINE_VMPTR(class AppDomain,       PTR_AppDomain,      VMPTR_AppDomain);
843
844 // Need to be careful not to annoy the compiler here since DT_CONTEXT is a typedef, not a struct.
845 // DEFINE_VMPTR(struct _CONTEXT,       PTR_CONTEXT,        VMPTR_CONTEXT);
846 #if defined(ALLOW_VMPTR_ACCESS)
847 typedef VMPTR_Base<DT_CONTEXT, PTR_CONTEXT> VMPTR_CONTEXT;
848 #else
849 typedef VMPTR_Base<DT_CONTEXT, void > VMPTR_CONTEXT;
850 #endif
851
852 // DomainFile is a base-class for a CLR module, with app-domain affinity.
853 // For domain-neutral modules (like mscorlib), there is a DomainFile instance
854 // for each appdomain the module lives in. 
855 // This is the canonical handle ICorDebug uses to a CLR module. 
856 DEFINE_VMPTR(class DomainFile,      PTR_DomainFile,     VMPTR_DomainFile);
857 DEFINE_VMPTR(class Module,          PTR_Module,         VMPTR_Module);
858
859 // DomainAssembly derives from DomainFile and represents a manifest module. 
860 DEFINE_VMPTR(class DomainAssembly,  PTR_DomainAssembly, VMPTR_DomainAssembly);
861 DEFINE_VMPTR(class Assembly,        PTR_Assembly,       VMPTR_Assembly);
862
863 DEFINE_VMPTR(class PEFile,          PTR_PEFile,         VMPTR_PEFile); 
864 DEFINE_VMPTR(class MethodDesc,      PTR_MethodDesc,     VMPTR_MethodDesc);
865 DEFINE_VMPTR(class FieldDesc,       PTR_FieldDesc,      VMPTR_FieldDesc);
866
867 // ObjectHandle is a safe way to represent an object into the GC heap. It gets updated
868 // when a GC occurs.
869 DEFINE_VMPTR(struct OBJECTHANDLE__, TADDR,              VMPTR_OBJECTHANDLE);
870
871 DEFINE_VMPTR(class TypeHandle,      PTR_TypeHandle,     VMPTR_TypeHandle);   
872
873 // A VMPTR_Thread represents a thread that has entered the runtime at some point. 
874 // It may or may not have executed managed code yet; and it may or may not have managed code
875 // on its callstack.
876 DEFINE_VMPTR(class Thread,          PTR_Thread,         VMPTR_Thread);
877
878 DEFINE_VMPTR(class Object,          PTR_Object,         VMPTR_Object);
879
880 DEFINE_VMPTR(class CrstBase,        PTR_Crst,           VMPTR_Crst);
881 DEFINE_VMPTR(class SimpleRWLock,    PTR_SimpleRWLock,   VMPTR_SimpleRWLock);
882 DEFINE_VMPTR(class SimpleRWLock,    PTR_SimpleRWLock,   VMPTR_RWLock);
883 DEFINE_VMPTR(struct ReJitInfo,       PTR_ReJitInfo,      VMPTR_ReJitInfo);
884 DEFINE_VMPTR(struct SharedReJitInfo, PTR_SharedReJitInfo, VMPTR_SharedReJitInfo);
885 DEFINE_VMPTR(class NativeCodeVersionNode, PTR_NativeCodeVersionNode, VMPTR_NativeCodeVersionNode);
886 DEFINE_VMPTR(class ILCodeVersionNode, PTR_ILCodeVersionNode, VMPTR_ILCodeVersionNode);
887
888 typedef CORDB_ADDRESS GENERICS_TYPE_TOKEN;
889
890
891 //-----------------------------------------------------------------------------
892 // We pass some fixed size strings in the IPC block.
893 // Helper class to wrap the buffer and protect against buffer overflows.
894 // This should be binary compatible w/ a wchar[] array.
895 //-----------------------------------------------------------------------------
896
897 template <int nMaxLengthIncludingNull>
898 class MSLAYOUT EmbeddedIPCString
899 {
900 public:
901     // Set, caller responsibility that wcslen(pData) < nMaxLengthIncludingNull
902     void SetString(const WCHAR * pData)
903     {
904         // If the string doesn't fit into the buffer, that's an issue (and so this is a real
905         // assert, not just a simplifying assumption). To fix it, either:
906         // - make the buffer larger
907         // - don't pass the string as an embedded string in the IPC block.
908         // This will truncate (rather than AV on the RS).
909         int ret;
910         ret = SafeCopy(pData);
911
912         // See comment above - caller should guarantee that buffer is large enough.
913         _ASSERTE(ret != STRUNCATE);
914     }
915
916     // Set a string from a substring. This will truncate if necessary.
917     void SetStringTruncate(const WCHAR * pData)
918     {
919         // ignore return value because truncation is ok.
920         SafeCopy(pData);
921     }
922
923     const WCHAR * GetString()
924     {
925         // For a null-termination just in case an issue in the debuggee process
926         // yields a malformed string.
927         m_data[nMaxLengthIncludingNull - 1] = W('\0');
928         return &m_data[0];
929     }
930     int GetMaxSize() const { return nMaxLengthIncludingNull; }
931
932 private:
933     int SafeCopy(const WCHAR * pData)
934     {
935         return wcsncpy_s(
936             m_data, nMaxLengthIncludingNull,
937             pData, _TRUNCATE);
938     }
939     WCHAR m_data[nMaxLengthIncludingNull];
940 };
941
942 //
943 // Types of events that can be sent between the Runtime Controller and
944 // the Debugger Interface. Some of these events are one way only, while
945 // others go both ways. The grouping of the event numbers is an attempt
946 // to show this distinction and perhaps even allow generic operations
947 // based on the type of the event.
948 //
949 enum DebuggerIPCEventType
950 {
951 #define IPC_EVENT_TYPE0(type, val)  type = val,
952 #define IPC_EVENT_TYPE1(type, val)  type = val,
953 #define IPC_EVENT_TYPE2(type, val)  type = val,
954 #include "dbgipceventtypes.h"
955 #undef IPC_EVENT_TYPE2
956 #undef IPC_EVENT_TYPE1
957 #undef IPC_EVENT_TYPE0
958 };
959
960 #ifdef _DEBUG
961
962 // This is a static debugging structure to help breaking at the right place.
963 // Debug only. This is to track the number of events that have been happened so far.
964 // User can choose to set break point base on the number of events.
965 // Variables are named as the event name with prefix m_iDebugCount. For example
966 // m_iDebugCount_DB_IPCE_BREAKPOINT if for event DB_IPCE_BREAKPOINT.
967 struct MSLAYOUT DebugEventCounter
968 {
969 // we don't need the event type 0
970 #define IPC_EVENT_TYPE0(type, val)
971 #define IPC_EVENT_TYPE1(type, val)  int m_iDebugCount_##type;
972 #define IPC_EVENT_TYPE2(type, val)  int m_iDebugCount_##type;
973 #include "dbgipceventtypes.h"
974 #undef IPC_EVENT_TYPE2
975 #undef IPC_EVENT_TYPE1
976 #undef IPC_EVENT_TYPE0
977 };
978 #endif // _DEBUG
979
980
981 #if !defined(DACCESS_COMPILE)
982
983 struct MSLAYOUT IPCEventTypeNameMapping
984     {
985             DebuggerIPCEventType    eventType;
986             const char *            eventName;
987 };
988
989 extern const IPCEventTypeNameMapping DECLSPEC_SELECTANY DbgIPCEventTypeNames[] =
990 {
991     #define IPC_EVENT_TYPE0(type, val)  { type, #type },
992     #define IPC_EVENT_TYPE1(type, val)  { type, #type },
993     #define IPC_EVENT_TYPE2(type, val)  { type, #type },
994     #include "dbgipceventtypes.h"
995     #undef IPC_EVENT_TYPE2
996     #undef IPC_EVENT_TYPE1
997     #undef IPC_EVENT_TYPE0
998     { DB_IPCE_INVALID_EVENT, "DB_IPCE_Error" }
999 };
1000
1001 const size_t nameCount = sizeof(DbgIPCEventTypeNames) / sizeof(DbgIPCEventTypeNames[0]);
1002
1003
1004 struct MSLAYOUT IPCENames // We use a class/struct so that the function can remain in a shared header file
1005 {
1006     static const DebuggerIPCEventType GetEventType(__in_z char * strEventType)
1007     {
1008         // pass in the string of event name and find the matching enum value
1009         // This is a linear search which is pretty slow. However, this is only used
1010         // at startup time when debug assert is turn on and with registry key set. So it is not that bad.
1011         //
1012         for (size_t i = 0; i < nameCount; i++)
1013         {
1014             if (_stricmp(DbgIPCEventTypeNames[i].eventName, strEventType) == 0)
1015                 return DbgIPCEventTypeNames[i].eventType;
1016         }
1017         return DB_IPCE_INVALID_EVENT;
1018     }
1019     static const char * GetName(DebuggerIPCEventType eventType)
1020     {
1021
1022         enum DbgIPCEventTypeNum
1023         {
1024         #define IPC_EVENT_TYPE0(type, val)  type##_Num,
1025         #define IPC_EVENT_TYPE1(type, val)  type##_Num,
1026         #define IPC_EVENT_TYPE2(type, val)  type##_Num,
1027         #include "dbgipceventtypes.h"
1028         #undef IPC_EVENT_TYPE2
1029         #undef IPC_EVENT_TYPE1
1030         #undef IPC_EVENT_TYPE0
1031         };
1032
1033         unsigned int i, lim;
1034
1035         if (eventType < DB_IPCE_DEBUGGER_FIRST)
1036         {
1037             i = DB_IPCE_RUNTIME_FIRST_Num + 1;
1038             lim = DB_IPCE_DEBUGGER_FIRST_Num;
1039         }
1040         else
1041         {
1042             i = DB_IPCE_DEBUGGER_FIRST_Num + 1;
1043             lim = nameCount;
1044         }
1045
1046         for (/**/; i < lim; i++)
1047         {
1048             if (DbgIPCEventTypeNames[i].eventType == eventType)
1049                 return DbgIPCEventTypeNames[i].eventName;
1050         }
1051
1052         return DbgIPCEventTypeNames[nameCount - 1].eventName;
1053     }
1054 };
1055
1056 #endif // !DACCESS_COMPILE
1057
1058 //
1059 // NOTE:  CPU-specific values below!
1060 //
1061 // DebuggerREGDISPLAY is very similar to the EE REGDISPLAY structure. It holds
1062 // register values that can be saved over calls for each frame in a stack
1063 // trace.
1064 //
1065 // DebuggerIPCE_FloatCount is the number of doubles in the processor's
1066 // floating point stack.
1067 //
1068 // <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
1069 // address of each register, too, to support using enregistered variables on non-leaf frames as args to a func eval. Its
1070 // very, very possible that we would rework the entire code base to just use the register's address instead of passing
1071 // both, but its way, way too late in V1 to undertake that, so I'm just using these addresses to suppport our one func
1072 // eval case. Clearly, this needs to be cleaned up post V1.
1073 //
1074 // -- Fri Feb 09 11:21:24 2001</TODO>
1075 //
1076
1077 struct MSLAYOUT DebuggerREGDISPLAY
1078 {
1079 #if defined(DBG_TARGET_X86)
1080     #define DebuggerIPCE_FloatCount 8
1081
1082     SIZE_T  Edi;
1083     void   *pEdi;
1084     SIZE_T  Esi;
1085     void   *pEsi;
1086     SIZE_T  Ebx;
1087     void   *pEbx;
1088     SIZE_T  Edx;
1089     void   *pEdx;
1090     SIZE_T  Ecx;
1091     void   *pEcx;
1092     SIZE_T  Eax;
1093     void   *pEax;
1094     SIZE_T  FP;
1095     void   *pFP;
1096     SIZE_T  SP;
1097     SIZE_T  PC;
1098
1099 #elif defined(DBG_TARGET_AMD64)
1100     #define DebuggerIPCE_FloatCount 16
1101
1102     SIZE_T  Rax;
1103     void   *pRax;
1104     SIZE_T  Rcx;
1105     void   *pRcx;
1106     SIZE_T  Rdx;
1107     void   *pRdx;
1108     SIZE_T  Rbx;
1109     void   *pRbx;
1110     SIZE_T  Rbp;
1111     void   *pRbp;
1112     SIZE_T  Rsi;
1113     void   *pRsi;
1114     SIZE_T  Rdi;
1115     void   *pRdi;
1116
1117     SIZE_T  R8;
1118     void   *pR8;
1119     SIZE_T  R9;
1120     void   *pR9;
1121     SIZE_T  R10;
1122     void   *pR10;
1123     SIZE_T  R11;
1124     void   *pR11;
1125     SIZE_T  R12;
1126     void   *pR12;
1127     SIZE_T  R13;
1128     void   *pR13;
1129     SIZE_T  R14;
1130     void   *pR14;
1131     SIZE_T  R15;
1132     void   *pR15;
1133
1134     SIZE_T  SP;
1135     SIZE_T  PC;
1136 #elif defined(DBG_TARGET_ARM)
1137     #define DebuggerIPCE_FloatCount 32
1138
1139     SIZE_T  R0;
1140     void   *pR0;
1141     SIZE_T  R1;
1142     void   *pR1;
1143     SIZE_T  R2;
1144     void   *pR2;
1145     SIZE_T  R3;
1146     void   *pR3;
1147     SIZE_T  R4;
1148     void   *pR4;
1149     SIZE_T  R5;
1150     void   *pR5;
1151     SIZE_T  R6;
1152     void   *pR6;
1153     SIZE_T  R7;
1154     void   *pR7;
1155     SIZE_T  R8;
1156     void   *pR8;
1157     SIZE_T  R9;
1158     void   *pR9;
1159     SIZE_T  R10;
1160     void   *pR10;
1161     SIZE_T  R11;
1162     void   *pR11;
1163     SIZE_T  R12;
1164     void   *pR12;
1165     SIZE_T  SP;
1166     void   *pSP;
1167     SIZE_T  LR;
1168     void   *pLR;
1169     SIZE_T  PC;
1170     void   *pPC;
1171 #elif defined(DBG_TARGET_ARM64)
1172     #define DebuggerIPCE_FloatCount 32
1173
1174     SIZE_T  X[29];
1175     SIZE_T  SP;
1176     SIZE_T  FP;
1177     SIZE_T  LR;
1178     SIZE_T  PC;
1179 #else
1180     #define DebuggerIPCE_FloatCount 1
1181
1182     SIZE_T PC;
1183     SIZE_T FP;
1184     SIZE_T SP;
1185     void   *pFP;
1186 #endif
1187 };
1188
1189 inline LPVOID GetSPAddress(const DebuggerREGDISPLAY * display)
1190 {
1191     return (LPVOID)&display->SP;
1192 }
1193
1194 #if !defined(DBG_TARGET_AMD64) && !defined(DBG_TARGET_ARM)
1195 inline LPVOID GetFPAddress(const DebuggerREGDISPLAY * display)
1196 {
1197     return (LPVOID)&display->FP;
1198 }
1199 #endif // !DBG_TARGET_AMD64
1200
1201
1202 class MSLAYOUT FramePointer
1203 {
1204 friend bool IsCloserToLeaf(FramePointer fp1, FramePointer fp2);
1205 friend bool IsCloserToRoot(FramePointer fp1, FramePointer fp2);
1206 friend bool IsEqualOrCloserToLeaf(FramePointer fp1, FramePointer fp2);
1207 friend bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2);
1208
1209 public:
1210
1211     static FramePointer MakeFramePointer(LPVOID sp)
1212     {
1213         LIMITED_METHOD_DAC_CONTRACT;
1214         FramePointer fp;
1215         fp.m_sp = sp;
1216         return fp;
1217     }
1218
1219     static FramePointer MakeFramePointer(UINT_PTR sp)
1220     {
1221         SUPPORTS_DAC;
1222         return MakeFramePointer((LPVOID)sp);
1223     }
1224
1225     inline bool operator==(FramePointer fp)
1226     {
1227         return (m_sp == fp.m_sp);
1228     }
1229
1230     inline bool operator!=(FramePointer fp)
1231     {
1232         return !(*this == fp);
1233     }
1234
1235     // This is needed because on the RS, the m_id values of CordbFrame and
1236     // CordbChain are really FramePointers.
1237     LPVOID GetSPValue() const
1238     {
1239         return m_sp;
1240     }
1241
1242
1243 private:
1244     // Declare some private constructors which signatures matching common usage of FramePointer
1245     // to prevent people from accidentally assigning a pointer to a FramePointer().
1246     FramePointer &operator=(LPVOID sp);
1247     FramePointer &operator=(BYTE* sp);
1248     FramePointer &operator=(const BYTE* sp);
1249
1250     LPVOID m_sp;
1251 };
1252
1253 // For non-IA64 platforms, we use stack pointers as frame pointers.
1254 // (Stack grows towards smaller address.)
1255 #define LEAF_MOST_FRAME FramePointer::MakeFramePointer((LPVOID)NULL)
1256 #define ROOT_MOST_FRAME FramePointer::MakeFramePointer((LPVOID)-1)
1257
1258 static_assert_no_msg(sizeof(FramePointer) == sizeof(void*));
1259
1260
1261 inline bool IsCloserToLeaf(FramePointer fp1, FramePointer fp2)
1262 {
1263     return (fp1.m_sp < fp2.m_sp);
1264 }
1265
1266 inline bool IsCloserToRoot(FramePointer fp1, FramePointer fp2)
1267 {
1268     return (fp1.m_sp > fp2.m_sp);
1269 }
1270
1271 inline bool IsEqualOrCloserToLeaf(FramePointer fp1, FramePointer fp2)
1272 {
1273     return !IsCloserToRoot(fp1, fp2);
1274 }
1275
1276 inline bool IsEqualOrCloserToRoot(FramePointer fp1, FramePointer fp2)
1277 {
1278     return !IsCloserToLeaf(fp1, fp2);
1279 }
1280
1281
1282 // struct DebuggerIPCE_FuncData:   DebuggerIPCE_FuncData holds data
1283 // to describe a given function, its
1284 // class, and a little bit about the code for the function. This is used
1285 // in the stack trace result data to pass function information back that
1286 // may be needed. Its also used when getting data about a specific function.
1287 //
1288 // void* nativeStartAddressPtr: Ptr to CORDB_ADDRESS, which is
1289 //          the address of the real start address of the native code.
1290 //          This field will be NULL only if the method hasn't been JITted
1291 //          yet (and thus no code is available).  Otherwise, it will be
1292 //          the adress of a CORDB_ADDRESS in the remote memory.  This
1293 //          CORDB_ADDRESS may be NULL, in which case the code is unavailable
1294 //          has been pitched (return CORDBG_E_CODE_NOT_AVAILABLE)
1295 //
1296 // SIZE_T nVersion: The version of the code that this instance of the
1297 //          function is using.
1298 struct MSLAYOUT DebuggerIPCE_FuncData
1299 {
1300     mdMethodDef funcMetadataToken;
1301     VMPTR_DomainFile vmDomainFile;
1302
1303     mdTypeDef   classMetadataToken;
1304
1305     void*       ilStartAddress;
1306     SIZE_T      ilSize;
1307
1308     SIZE_T      currentEnCVersion;
1309
1310     mdSignature  localVarSigToken;
1311
1312
1313 };
1314
1315 // struct DebuggerIPCE_JITFuncData:   DebuggerIPCE_JITFuncData holds
1316 // a little bit about the JITted code for the function.
1317 //
1318 // void* nativeStartAddressPtr: Ptr to CORDB_ADDRESS, which is
1319 //          the address of the real start address of the native code.
1320 //          This field will be NULL only if the method hasn't been JITted
1321 //          yet (and thus no code is available).  Otherwise, it will be
1322 //          the address of a CORDB_ADDRESS in the remote memory.  This
1323 //          CORDB_ADDRESS may be NULL, in which case the code is unavailable
1324 //          or has been pitched (return CORDBG_E_CODE_NOT_AVAILABLE)
1325 //
1326 // SIZE_T nativeSize: Size of the native code.
1327 //
1328 // SIZE_T nativeOffset: Offset from the beginning of the function,
1329 //          in bytes.  This may be non-zero even when nativeStartAddressPtr
1330 //          is NULL
1331 // void * nativeCodeJITInfoToken: An opaque value to hand back to the left
1332 //          side when fetching the JITInfo for the native code, i.e. the
1333 //          IL->native maps for the variables.  This may be NULL if no JITInfo is available.
1334 // void * nativeCodeMethodDescToken: An opaque value to hand back to the left
1335 //          side when fetching the code.  In addition this token can act as the
1336 //          unique identity for the native code in the case where there are
1337 //          multiple blobs of native code per IL method (i.e. if the method is
1338 //          generic code of some kind)
1339 // BOOL isInstantiatedGeneric: Indicates if the method is
1340 //          generic code of some kind.
1341 // BOOL jsutAfterILThrow: indicates that code just threw a software exception and
1342 //          nativeOffset points to an instruction just after [call IL_Throw].
1343 //          This is being used to figure out a real offset of the exception origin.  
1344 //          By subtracting STACKWALK_CONTROLPC_ADJUST_OFFSET from nativeOffset you can get 
1345 //          an address somewhere inside [call IL_Throw] instruction.
1346 // void *ilToNativeMapAddr etc.: If nativeCodeJITInfoToken is not NULL then these
1347 //          specify the table giving the mapping of IPs.
1348 struct MSLAYOUT DebuggerIPCE_JITFuncData
1349 {
1350     TADDR       nativeStartAddressPtr;
1351     SIZE_T      nativeHotSize;
1352
1353     // If we have a cold region, need its size & the pointer to where starts.
1354     TADDR       nativeStartAddressColdPtr;
1355     SIZE_T      nativeColdSize;
1356
1357
1358     SIZE_T      nativeOffset;
1359     LSPTR_DJI   nativeCodeJITInfoToken;
1360     VMPTR_MethodDesc vmNativeCodeMethodDescToken;
1361
1362 #ifdef WIN64EXCEPTIONS
1363     BOOL         fIsFilterFrame;
1364     SIZE_T       parentNativeOffset;
1365     FramePointer fpParentOrSelf;
1366 #endif // WIN64EXCEPTIONS
1367
1368     // indicates if the MethodDesc is a generic function or a method inside a generic class (or
1369     // both!).
1370     BOOL         isInstantiatedGeneric;
1371
1372     // this is the version of the jitted code
1373     SIZE_T       enCVersion;
1374
1375     BOOL         jsutAfterILThrow;
1376 };
1377
1378 //
1379 // DebuggerIPCE_STRData holds data for each stack frame or chain. This data is passed
1380 // from the RC to the DI during a stack walk.
1381 //
1382 #if defined(_MSC_VER)
1383 #pragma warning( push )
1384 #pragma warning( disable:4324 ) // the compiler pads a structure to comply with alignment requirements
1385 #endif                          // ARM context structures have a 16-byte alignment requirement
1386 struct MSLAYOUT DebuggerIPCE_STRData
1387 {
1388     FramePointer            fp;
1389     // @dbgtodo  stackwalker/shim- Ideally we should be able to get rid of the DebuggerREGDISPLAY and just use the CONTEXT.
1390     DT_CONTEXT              ctx;
1391     DebuggerREGDISPLAY      rd;
1392     bool                    quicklyUnwound;
1393
1394     VMPTR_AppDomain         vmCurrentAppDomainToken;
1395
1396
1397     enum EType
1398     {
1399         cMethodFrame = 0,
1400         cChain,
1401         cStubFrame,
1402         cRuntimeNativeFrame
1403     } eType;
1404
1405     union MSLAYOUT
1406     {
1407         // Data for a chain
1408         struct MSLAYOUT
1409         {
1410             CorDebugChainReason chainReason;
1411             bool                managed;
1412         } u;
1413
1414         // Data for a Method
1415         struct MSLAYOUT
1416         {
1417             struct DebuggerIPCE_FuncData funcData;
1418             struct DebuggerIPCE_JITFuncData jitFuncData;
1419             SIZE_T                       ILOffset;
1420             CorDebugMappingResult        mapping;
1421
1422             bool        fVarArgs;
1423
1424             // Indicates whether the managed method has any metadata.
1425             // Some dynamic methods such as IL stubs and LCG methods don't have any metadata.
1426             // This is used only by the V3 stackwalker, not the V2 one, because we only 
1427             // expose dynamic methods as real stack frames in V3.
1428             bool        fNoMetadata;
1429
1430             TADDR       taAmbientESP;
1431
1432             GENERICS_TYPE_TOKEN exactGenericArgsToken;
1433             DWORD               dwExactGenericArgsTokenIndex;
1434
1435         } v;
1436
1437         // Data for an Stub Frame.
1438         struct MSLAYOUT
1439         {
1440             mdMethodDef funcMetadataToken;
1441             VMPTR_DomainFile vmDomainFile;
1442             VMPTR_MethodDesc vmMethodDesc;
1443             CorDebugInternalFrameType frameType;
1444         } stubFrame;
1445
1446     };
1447 };
1448 #if defined(_MSC_VER)
1449 #pragma warning( pop )
1450 #endif
1451
1452 //
1453 // DebuggerIPCE_BasicTypeData and DebuggerIPCE_ExpandedTypeData
1454 // hold data for each type sent across the
1455 // boundary, whether it be a constructed type List<String> or a non-constructed
1456 // type such as String, Foo or Object.
1457 //
1458 // Logically speaking DebuggerIPCE_BasicTypeData might just be "typeHandle", as
1459 // we could then send further events to ask what the elementtype, typeToken and moduleToken
1460 // are for the type handle.  But as
1461 // nearly all types are non-generic we send across even the basic type information in
1462 // the slightly expanded form shown below, sending the element type and the
1463 // tokens with the type handle itself. The fields debuggerModuleToken, metadataToken and typeHandle
1464 // are only used as follows:
1465 //                                   elementType    debuggerModuleToken metadataToken      typeHandle
1466 //     E_T_INT8    :                  E_T_INT8         No                     No              No
1467 //     Boxed E_T_INT8:                E_T_CLASS        No                     No              No
1468 //     E_T_CLASS, non-generic class:  E_T_CLASS       Yes                    Yes              No
1469 //     E_T_VALUETYPE, non-generic:    E_T_VALUETYPE   Yes                    Yes              No
1470 //     E_T_CLASS,     generic class:  E_T_CLASS       Yes                    Yes             Yes
1471 //     E_T_VALUETYPE, generic class:  E_T_VALUETYPE   Yes                    Yes             Yes
1472 //     E_T_BYREF                   :  E_T_BYREF        No                     No             Yes
1473 //     E_T_PTR                     :  E_T_PTR          No                     No             Yes
1474 //     E_T_ARRAY etc.              :  E_T_ARRAY        No                     No             Yes
1475 //     E_T_FNPTR etc.              :  E_T_FNPTR        No                     No             Yes
1476 // This allows us to always set "typeHandle" to NULL except when dealing with highly nested
1477 // types or function-pointer types (the latter are too complexe to transfer over in one hit).
1478 //
1479
1480 struct MSLAYOUT DebuggerIPCE_BasicTypeData
1481 {
1482     CorElementType  elementType;
1483     mdTypeDef       metadataToken;
1484     VMPTR_Module     vmModule;
1485     VMPTR_DomainFile vmDomainFile;
1486     VMPTR_TypeHandle vmTypeHandle;
1487 };
1488
1489 // DebuggerIPCE_ExpandedTypeData contains more information showing further
1490 // details for array types, byref types etc.
1491 // Whenever you fetch type information from the left-side
1492 // you get back one of these.  These in turn contain further
1493 // DebuggerIPCE_BasicTypeData's and typeHandles which you can
1494 // then query to get further information about the type parameters.
1495 // This copes with the nested cases, e.g. jagged arrays,
1496 // String ****, &(String*), Pair<String,Pair<String>>
1497 // and so on.
1498 //
1499 // So this type information is not "fully expanded", it's just a little
1500 // more detail then DebuggerIPCE_BasicTypeData.  For type
1501 // instantiatons (e.g. List<int>) and
1502 // function pointer types you will need to make further requests for
1503 // information about the type parameters.
1504 // For array types there is always only one type parameter so
1505 // we include that as part of the expanded data.
1506 //
1507 //
1508 struct MSLAYOUT DebuggerIPCE_ExpandedTypeData
1509 {
1510     CorElementType  elementType; // Note this is _never_ E_T_VAR, E_T_WITH or E_T_MVAR
1511     union MSLAYOUT
1512     {
1513         // used for E_T_CLASS and E_T_VALUECLASS, E_T_PTR, E_T_BYREF etc.
1514         // For non-constructed E_T_CLASS or E_T_VALUECLASS the tokens will be set and the typeHandle will be NULL
1515         // For constructed E_T_CLASS or E_T_VALUECLASS the tokens will be set and the typeHandle will be non-NULL
1516         // For E_T_PTR etc. the tokens will be NULL and the typeHandle will be non-NULL.
1517         struct MSLAYOUT
1518          {
1519             mdTypeDef       metadataToken;
1520             VMPTR_Module vmModule;
1521             VMPTR_DomainFile vmDomainFile;
1522             VMPTR_TypeHandle typeHandle; // if non-null then further fetches will be needed to get type arguments
1523         } ClassTypeData;
1524
1525         // used for E_T_PTR, E_T_BYREF etc.
1526         struct MSLAYOUT
1527          {
1528             DebuggerIPCE_BasicTypeData unaryTypeArg;  // used only when sending back to debugger
1529         } UnaryTypeData;
1530
1531
1532         // used for E_T_ARRAY etc.
1533         struct MSLAYOUT
1534         {
1535           DebuggerIPCE_BasicTypeData arrayTypeArg; // used only when sending back to debugger
1536             DWORD           arrayRank;
1537         } ArrayTypeData;
1538
1539         // used for E_T_FNPTR
1540         struct MSLAYOUT
1541          {
1542             VMPTR_TypeHandle typeHandle; // if non-null then further fetches needed to get type arguments
1543         } NaryTypeData;
1544
1545     };
1546 };
1547
1548 // DebuggerIPCE_TypeArgData is used when sending type arguments
1549 // across to a funceval.  It contains the DebuggerIPCE_ExpandedTypeData describing the
1550 // essence of the type, but the typeHandle and other
1551 // BasicTypeData fields should be zero and will be ignored.
1552 // The DebuggerIPCE_ExpandedTypeData is then followed
1553 // by the required number of type arguments, each of which
1554 // will be a further DebuggerIPCE_TypeArgData record in the stream of
1555 // flattened type argument data.
1556 struct MSLAYOUT DebuggerIPCE_TypeArgData
1557 {
1558     DebuggerIPCE_ExpandedTypeData  data;
1559     unsigned int                   numTypeArgs; // number of immediate children on the type tree
1560 };
1561
1562
1563 //
1564 // DebuggerIPCE_ObjectData holds the results of a
1565 // GetAndSendObjectInfo, i.e., all the info about an object that the
1566 // Right Side would need to access it. (This include array, string,
1567 // and nstruct info.)
1568 //
1569 struct MSLAYOUT DebuggerIPCE_ObjectData
1570 {
1571     void           *objRef;
1572     bool            objRefBad;
1573     SIZE_T          objSize;
1574
1575     // Offset from the beginning of the object to the beginning of the first field
1576     SIZE_T          objOffsetToVars;
1577
1578     // The type of the object....
1579     struct DebuggerIPCE_ExpandedTypeData objTypeData;
1580
1581     union MSLAYOUT
1582     {
1583         struct MSLAYOUT
1584         {
1585             SIZE_T          length;
1586             SIZE_T          offsetToStringBase;
1587         } stringInfo;
1588
1589         struct MSLAYOUT
1590         {
1591             SIZE_T          rank;
1592             SIZE_T          offsetToArrayBase;
1593             SIZE_T          offsetToLowerBounds; // 0 if not present
1594             SIZE_T          offsetToUpperBounds; // 0 if not present
1595             SIZE_T          componentCount;
1596             SIZE_T          elementSize;
1597         } arrayInfo;
1598
1599         struct MSLAYOUT
1600         {
1601             struct DebuggerIPCE_BasicTypeData typedByrefType; // the type of the thing contained in a typedByref...
1602         } typedByrefInfo;
1603     };
1604 };
1605
1606 //
1607 // Remote enregistered info used by CordbValues and for passing
1608 // variable homes between the left and right sides during a func eval.
1609 //
1610
1611 enum RemoteAddressKind
1612 {
1613     RAK_NONE = 0,
1614     RAK_REG,
1615     RAK_REGREG,
1616     RAK_REGMEM,
1617     RAK_MEMREG,
1618     RAK_FLOAT,
1619     RAK_END
1620 };
1621
1622 const CORDB_ADDRESS kLeafFrameRegAddr = 0;
1623 const CORDB_ADDRESS kNonLeafFrameRegAddr = (CORDB_ADDRESS)(-1);
1624
1625 struct MSLAYOUT RemoteAddress
1626 {
1627     RemoteAddressKind    kind;
1628     void                *frame;
1629
1630     CorDebugRegister     reg1;
1631     void                *reg1Addr;
1632     SIZE_T               reg1Value;         // this is the actual value of the register
1633
1634     union MSLAYOUT
1635     {
1636         struct MSLAYOUT
1637         {
1638             CorDebugRegister  reg2;
1639             void             *reg2Addr;
1640             SIZE_T            reg2Value;    // this is the actual value of the register
1641         } u;
1642
1643         CORDB_ADDRESS    addr;
1644         DWORD            floatIndex;
1645     };
1646 };
1647
1648 //
1649 // DebuggerIPCE_FuncEvalType specifies the type of a function
1650 // evaluation that will occur.
1651 //
1652 enum DebuggerIPCE_FuncEvalType
1653 {
1654     DB_IPCE_FET_NORMAL,
1655     DB_IPCE_FET_NEW_OBJECT,
1656     DB_IPCE_FET_NEW_OBJECT_NC,
1657     DB_IPCE_FET_NEW_STRING,
1658     DB_IPCE_FET_NEW_ARRAY,
1659     DB_IPCE_FET_RE_ABORT
1660 };
1661
1662
1663 enum NameChangeType
1664 {
1665     APP_DOMAIN_NAME_CHANGE,
1666     THREAD_NAME_CHANGE
1667 };
1668
1669 //
1670 // DebuggerIPCE_FuncEvalArgData holds data for each argument to a
1671 // function evaluation.
1672 //
1673 struct MSLAYOUT DebuggerIPCE_FuncEvalArgData
1674 {
1675     RemoteAddress     argHome;  // enregistered variable home
1676     void             *argAddr;  // address if not enregistered
1677     CorElementType    argElementType;
1678     unsigned int      fullArgTypeNodeCount; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types)
1679     void             *fullArgType; // Pointer to LS (DebuggerIPCE_TypeArgData *) buffer holding full description of the argument type (if needed - only needed for struct types)
1680     BYTE              argLiteralData[8]; // copy of generic value data
1681     bool              argIsLiteral; // true if value is in argLiteralData
1682     bool              argIsHandleValue; // true if argAddr is OBJECTHANDLE
1683 };
1684
1685
1686 //
1687 // DebuggerIPCE_FuncEvalInfo holds info necessary to setup a func eval
1688 // operation.
1689 //
1690 struct MSLAYOUT DebuggerIPCE_FuncEvalInfo
1691 {
1692     VMPTR_Thread               vmThreadToken;
1693     DebuggerIPCE_FuncEvalType  funcEvalType;
1694     mdMethodDef                funcMetadataToken;
1695     mdTypeDef                  funcClassMetadataToken;
1696     VMPTR_DomainFile           vmDomainFile;
1697     RSPTR_CORDBEVAL            funcEvalKey;
1698     bool                       evalDuringException;
1699
1700     unsigned int               argCount;
1701     unsigned int               genericArgsCount;
1702     unsigned int               genericArgsNodeCount;
1703
1704     SIZE_T                     stringSize;
1705
1706     SIZE_T                     arrayRank;
1707 };
1708
1709
1710 //
1711 // Used in DebuggerIPCFirstChanceData. This tells the LS what action to take within the hijack
1712 //
1713 enum HijackAction
1714 {
1715     HIJACK_ACTION_EXIT_UNHANDLED,
1716     HIJACK_ACTION_EXIT_HANDLED,
1717     HIJACK_ACTION_WAIT
1718 };
1719
1720 //
1721 // DebuggerIPCFirstChanceData holds info communicated from the LS to the RS when signaling that an exception does not
1722 // belong to the runtime from a first chance hijack. This is used when Win32 debugging only.
1723 //
1724 struct MSLAYOUT DebuggerIPCFirstChanceData
1725 {
1726     LSPTR_CONTEXT     pLeftSideContext;
1727     HijackAction      action;
1728     UINT              debugCounter;
1729 };
1730
1731 //
1732 // DebuggerIPCSecondChanceData holds info communicated from the RS
1733 // to the LS when setting up a second chance exception hijack. This is
1734 // used when Win32 debugging only.
1735 //
1736 struct MSLAYOUT DebuggerIPCSecondChanceData
1737 {
1738     DT_CONTEXT       threadContext;
1739 };
1740
1741
1742
1743 //-----------------------------------------------------------------------------
1744 // This struct holds pointer from the LS and needs to copy to
1745 // the RS. We have to free the memory on the RS.
1746 // The transfer function is called when the RS first reads the event. At this point, 
1747 // the LS is stopped while sending the event. Thus the LS pointers only need to be
1748 // valid while the LS is in SendIPCEvent.
1749 //
1750 // Since this data is in an IPC/Marshallable block, it can't have any Ctors (holders)
1751 // in it. 
1752 //-----------------------------------------------------------------------------
1753 struct MSLAYOUT Ls_Rs_BaseBuffer
1754 {
1755 #ifdef RIGHT_SIDE_COMPILE
1756 protected:
1757     // copy data can happen on both LS and RS. In LS case,
1758     // ReadProcessMemory is really reading from its own process memory.
1759     //
1760     void CopyLSDataToRSWorker(ICorDebugDataTarget * pTargethProcess);
1761     
1762     // retrieve the RS data and own it
1763     BYTE *TransferRSDataWorker()
1764     {
1765         BYTE *pbRS = m_pbRS;
1766         m_pbRS = NULL;
1767         return pbRS;
1768     }
1769 public:
1770     
1771
1772     void CleanUp()
1773     {
1774         if (m_pbRS != NULL)
1775         {
1776             delete [] m_pbRS;
1777             m_pbRS = NULL;
1778         }
1779     }
1780 #else
1781 public:
1782     // Only LS can call this API
1783     void SetLsData(BYTE *pbLS, DWORD cbSize)
1784     {
1785         m_pbRS = NULL;
1786         m_pbLS = pbLS;
1787         m_cbSize = cbSize;
1788     }
1789 #endif // RIGHT_SIDE_COMPILE
1790
1791 public:
1792     // Common APIs.
1793     DWORD  GetSize() { return m_cbSize; }
1794
1795
1796
1797 protected:
1798     // Size of data in bytes 
1799     DWORD  m_cbSize;
1800
1801     // If this is non-null, pointer into LS for buffer.
1802     // LS can free this after the debug event is continued.
1803     BYTE  *m_pbLS; // @dbgtodo  cross-plat- for cross-platform purposes, this should be a TADDR
1804
1805     // If this is non-null, pointer into RS for buffer. RS must then free this. 
1806     // This buffer was copied from the LS (via CopyLSDataToRSWorker).
1807     BYTE  *m_pbRS;
1808 };
1809
1810 //-----------------------------------------------------------------------------
1811 // Byte wrapper around the buffer.
1812 //-----------------------------------------------------------------------------
1813 struct MSLAYOUT Ls_Rs_ByteBuffer : public Ls_Rs_BaseBuffer
1814 {
1815 #ifdef RIGHT_SIDE_COMPILE
1816     BYTE *GetRSPointer() 
1817     { 
1818         return m_pbRS;
1819     }
1820
1821     void CopyLSDataToRS(ICorDebugDataTarget * pTarget);
1822     BYTE *TransferRSData()
1823     {
1824         return TransferRSDataWorker();
1825     }
1826 #endif    
1827 };
1828
1829 //-----------------------------------------------------------------------------
1830 // Wrapper around a Ls_rS_Buffer to get it as a string.
1831 // This can also do some sanity checking.
1832 //-----------------------------------------------------------------------------
1833 struct MSLAYOUT Ls_Rs_StringBuffer : public Ls_Rs_BaseBuffer
1834 {
1835 #ifdef RIGHT_SIDE_COMPILE
1836     const WCHAR * GetString()
1837     {
1838         return reinterpret_cast<const WCHAR*> (m_pbRS);
1839     }
1840
1841     // Copy over the string.
1842     void CopyLSDataToRS(ICorDebugDataTarget * pTarget);
1843
1844     // Caller will pick up ownership.
1845     // Since caller will delete this data, we can't give back a constant pointer.
1846     WCHAR * TransferStringData()
1847     {
1848         return reinterpret_cast<WCHAR*> (TransferRSDataWorker());
1849     }
1850 #endif  
1851 };
1852
1853
1854 // Data for an Managed Debug Assistant Probe (MDA).
1855 struct MSLAYOUT DebuggerMDANotification
1856 {
1857     Ls_Rs_StringBuffer szName;
1858     Ls_Rs_StringBuffer szDescription;
1859     Ls_Rs_StringBuffer szXml;
1860     DWORD        dwOSThreadId;
1861     CorDebugMDAFlags flags;
1862 };
1863
1864
1865 // The only remaining problem is that register number mappings are different for each platform. It turns out
1866 // that the debugger only uses REGNUM_SP and REGNUM_AMBIENT_SP though, so we can just virtualize these two for
1867 // the target platform.
1868 // Keep this is sync with the definitions in inc/corinfo.h.
1869 #if defined(DBG_TARGET_X86)
1870 #define DBG_TARGET_REGNUM_SP 4
1871 #define DBG_TARGET_REGNUM_AMBIENT_SP 9
1872 #ifdef _TARGET_X86_
1873 static_assert_no_msg(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP);
1874 static_assert_no_msg(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP);
1875 #endif // _TARGET_X86_
1876 #elif defined(DBG_TARGET_AMD64)
1877 #define DBG_TARGET_REGNUM_SP 4
1878 #define DBG_TARGET_REGNUM_AMBIENT_SP 17
1879 #ifdef _TARGET_AMD64_
1880 static_assert_no_msg(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP);
1881 static_assert_no_msg(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP);
1882 #endif // _TARGET_AMD64_
1883 #elif defined(DBG_TARGET_ARM)
1884 #define DBG_TARGET_REGNUM_SP 13
1885 #define DBG_TARGET_REGNUM_AMBIENT_SP 17
1886 #ifdef _TARGET_ARM_
1887 C_ASSERT(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP);
1888 C_ASSERT(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP);
1889 #endif // _TARGET_ARM_
1890 #elif defined(DBG_TARGET_ARM64)
1891 #define DBG_TARGET_REGNUM_SP 31
1892 #define DBG_TARGET_REGNUM_AMBIENT_SP 34
1893 #ifdef _TARGET_ARM64_
1894 C_ASSERT(DBG_TARGET_REGNUM_SP == ICorDebugInfo::REGNUM_SP);
1895 C_ASSERT(DBG_TARGET_REGNUM_AMBIENT_SP == ICorDebugInfo::REGNUM_AMBIENT_SP);
1896 #endif // _TARGET_ARM64_
1897 #else
1898 #error Target registers are not defined for this platform
1899 #endif
1900
1901
1902 //
1903 // Event structure that is passed between the Runtime Controller and the
1904 // Debugger Interface. Some types of events are a fixed size and have
1905 // entries in the main union, while others are variable length and have
1906 // more specialized data structures that are attached to the end of this
1907 // structure.
1908 //
1909 struct MSLAYOUT DebuggerIPCEvent
1910 {
1911     DebuggerIPCEvent*       next;
1912     DebuggerIPCEventType    type;
1913     DWORD             processId;
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_ */