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