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