Merge pull request #13605 from BruceForstall/ScopeEnvSettings
[platform/upstream/coreclr.git] / src / debug / inc / dbgtargetcontext.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 #ifndef __DBG_TARGET_CONTEXT_INCLUDED
6 #define __DBG_TARGET_CONTEXT_INCLUDED
7
8 #include <dbgportable.h>
9 #include <stddef.h>
10 #include "crosscomp.h"
11
12 //
13 // The right side of the debugger can now be built to target multiple platforms. This means it is no longer
14 // safe to use the CONTEXT structure directly: the context of the platform we're building for might not match
15 // that of the one the debugger is targetting. So now all right side code will use the DT_CONTEXT abstraction
16 // instead. When the debugger target is the local platform this will just resolve back into CONTEXT, but cross
17 // platform we'll provide a hand-rolled version.
18 //
19
20 //
21 // For cross platform cases we also need to provide a helper function for byte-swapping a context structure
22 // should the endian-ness of the debugger and debuggee platforms differ. This is called ByteSwapContext and is
23 // obviously a no-op for those cases where the left and right sides agree on storage format.
24 //
25 // NOTE: Any changes to the field layout of DT_CONTEXT must be tracked in the associated definition of
26 // ByteSwapContext.
27 //
28
29 // For now, the only cross-platform CONTEXTs we support are x86/PAL and ARM/Win. Look in
30 // rotor/pal/inc/rotor_pal.h for the original PAL definitions.
31
32 //
33 // **** NOTE: Keep these in sync with rotor/pal/inc/rotor_pal.h ****
34 //
35
36 // This odd define pattern is needed because in DBI we set _TARGET_ to match the host and
37 // DBG_TARGET to control our targeting. In x-plat DBI DBG_TARGET won't match _TARGET_ and
38 // DBG_TARGET needs to take precedence
39 #if defined(DBG_TARGET_X86)
40 #define DTCONTEXT_IS_X86
41 #elif defined (DBG_TARGET_AMD64)
42 #define DTCONTEXT_IS_AMD64
43 #elif defined (DBG_TARGET_ARM)
44 #define DTCONTEXT_IS_ARM
45 #elif defined (DBG_TARGET_ARM64)
46 #define DTCONTEXT_IS_ARM64
47 #elif defined (_TARGET_X86_)
48 #define DTCONTEXT_IS_X86
49 #elif defined (_TARGET_AMD64_)
50 #define DTCONTEXT_IS_AMD64
51 #elif defined (_TARGET_ARM_)
52 #define DTCONTEXT_IS_ARM
53 #elif defined (_TARGET_ARM64_)
54 #define DTCONTEXT_IS_ARM64
55 #endif
56
57 #if defined(DTCONTEXT_IS_X86)
58
59 #define DT_SIZE_OF_80387_REGISTERS      80
60
61 #define DT_CONTEXT_i386            0x00010000
62 #define DT_CONTEXT_CONTROL         (DT_CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
63 #define DT_CONTEXT_INTEGER         (DT_CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
64 #define DT_CONTEXT_SEGMENTS        (DT_CONTEXT_i386 | 0x00000004L)
65 #define DT_CONTEXT_FLOATING_POINT  (DT_CONTEXT_i386 | 0x00000008L) // 387 state
66 #define DT_CONTEXT_DEBUG_REGISTERS (DT_CONTEXT_i386 | 0x00000010L)
67
68 #define DT_CONTEXT_FULL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_SEGMENTS)
69 #define DT_CONTEXT_EXTENDED_REGISTERS  (DT_CONTEXT_i386 | 0x00000020L)
70
71 #define DT_MAXIMUM_SUPPORTED_EXTENSION     512
72
73 typedef struct {
74     DWORD   ControlWord;
75     DWORD   StatusWord;
76     DWORD   TagWord;
77     DWORD   ErrorOffset;
78     DWORD   ErrorSelector;
79     DWORD   DataOffset;
80     DWORD   DataSelector;
81     BYTE    RegisterArea[DT_SIZE_OF_80387_REGISTERS];
82     DWORD   Cr0NpxState;
83 } DT_FLOATING_SAVE_AREA;
84
85 typedef struct {
86     ULONG ContextFlags;
87
88     ULONG   Dr0;
89     ULONG   Dr1;
90     ULONG   Dr2;
91     ULONG   Dr3;
92     ULONG   Dr6;
93     ULONG   Dr7;
94
95     DT_FLOATING_SAVE_AREA FloatSave;
96
97     ULONG   SegGs;
98     ULONG   SegFs;
99     ULONG   SegEs;
100     ULONG   SegDs;
101
102     ULONG   Edi;
103     ULONG   Esi;
104     ULONG   Ebx;
105     ULONG   Edx;
106     ULONG   Ecx;
107     ULONG   Eax;
108
109     ULONG   Ebp;
110     ULONG   Eip;
111     ULONG   SegCs;
112     ULONG   EFlags;
113     ULONG   Esp;
114     ULONG   SegSs;
115
116     UCHAR   ExtendedRegisters[DT_MAXIMUM_SUPPORTED_EXTENSION];
117
118 } DT_CONTEXT;
119
120 // Since the target is little endian in this case we only have to provide a real implementation of
121 // ByteSwapContext if the platform we're building on is big-endian.
122 #ifdef BIGENDIAN
123 inline void ByteSwapContext(DT_CONTEXT *pContext)
124 {
125     // Our job is simplified since the context has large contiguous ranges with fields of the same size. Keep
126     // the following logic in sync with the definition of DT_CONTEXT above.
127     BYTE *pbContext = (BYTE*)pContext;
128
129     // The first span consists of 4 byte fields.
130     DWORD cbFields = (offsetof(DT_CONTEXT, FloatSave) + offsetof(DT_FLOATING_SAVE_AREA, RegisterArea)) / 4;
131     for (DWORD i = 0; i < cbFields; i++)
132     {
133         ByteSwapPrimitive(pbContext, pbContext, 4);
134         pbContext += 4;
135     }
136
137     // Then there's a float save area containing 8 byte fields.
138     cbFields = sizeof(pContext->FloatSave.RegisterArea);
139     for (DWORD i = 0; i < cbFields; i++)
140     {
141         ByteSwapPrimitive(pbContext, pbContext, 8);
142         pbContext += 8;
143     }
144
145     // Back to 4 byte fields.
146     cbFields = (offsetof(DT_CONTEXT, ExtendedRegisters) - offsetof(DT_CONTEXT, SegGs)) / 4;
147     for (DWORD i = 0; i < cbFields; i++)
148     {
149         ByteSwapPrimitive(pbContext, pbContext, 4);
150         pbContext += 4;
151     }
152
153     // We don't know the formatting of the extended register area, but the debugger doesn't access this data
154     // on the left side, so just leave it in left-side format for now.
155
156     // Validate that we converted up to where we think we did as a hedge against DT_CONTEXT layout changes.
157     _PASSERT((pbContext - ((BYTE*)pContext)) == (sizeof(DT_CONTEXT) - sizeof(pContext->ExtendedRegisters)));
158 }
159 #else // BIGENDIAN
160 inline void ByteSwapContext(DT_CONTEXT *pContext)
161 {
162 }
163 #endif // BIGENDIAN
164
165 #elif defined(DTCONTEXT_IS_AMD64)
166
167 #define DT_CONTEXT_AMD64            0x00100000L
168
169 #define DT_CONTEXT_CONTROL          (DT_CONTEXT_AMD64 | 0x00000001L)
170 #define DT_CONTEXT_INTEGER          (DT_CONTEXT_AMD64 | 0x00000002L)
171 #define DT_CONTEXT_SEGMENTS         (DT_CONTEXT_AMD64 | 0x00000004L)
172 #define DT_CONTEXT_FLOATING_POINT   (DT_CONTEXT_AMD64 | 0x00000008L)
173 #define DT_CONTEXT_DEBUG_REGISTERS  (DT_CONTEXT_AMD64 | 0x00000010L)
174
175 #define DT_CONTEXT_FULL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_FLOATING_POINT)
176 #define DT_CONTEXT_ALL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_SEGMENTS | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_DEBUG_REGISTERS)
177
178 typedef struct  {
179     ULONGLONG Low;
180     LONGLONG High;
181 } DT_M128A;
182
183 typedef struct  {
184     WORD   ControlWord;
185     WORD   StatusWord;
186     BYTE  TagWord;
187     BYTE  Reserved1;
188     WORD   ErrorOpcode;
189     DWORD ErrorOffset;
190     WORD   ErrorSelector;
191     WORD   Reserved2;
192     DWORD DataOffset;
193     WORD   DataSelector;
194     WORD   Reserved3;
195     DWORD MxCsr;
196     DWORD MxCsr_Mask;
197     DT_M128A FloatRegisters[8];
198     DT_M128A XmmRegisters[16];
199     BYTE  Reserved4[96];
200 } DT_XMM_SAVE_AREA32;
201
202 typedef struct DECLSPEC_ALIGN(16) {
203
204     DWORD64 P1Home;
205     DWORD64 P2Home;
206     DWORD64 P3Home;
207     DWORD64 P4Home;
208     DWORD64 P5Home;
209     DWORD64 P6Home;
210
211     DWORD ContextFlags;
212     DWORD MxCsr;
213
214     WORD   SegCs;
215     WORD   SegDs;
216     WORD   SegEs;
217     WORD   SegFs;
218     WORD   SegGs;
219     WORD   SegSs;
220     DWORD EFlags;
221
222     DWORD64 Dr0;
223     DWORD64 Dr1;
224     DWORD64 Dr2;
225     DWORD64 Dr3;
226     DWORD64 Dr6;
227     DWORD64 Dr7;
228
229     DWORD64 Rax;
230     DWORD64 Rcx;
231     DWORD64 Rdx;
232     DWORD64 Rbx;
233     DWORD64 Rsp;
234     DWORD64 Rbp;
235     DWORD64 Rsi;
236     DWORD64 Rdi;
237     DWORD64 R8;
238     DWORD64 R9;
239     DWORD64 R10;
240     DWORD64 R11;
241     DWORD64 R12;
242     DWORD64 R13;
243     DWORD64 R14;
244     DWORD64 R15;
245
246     DWORD64 Rip;
247
248     union {
249         DT_XMM_SAVE_AREA32 FltSave;
250         struct {
251             DT_M128A Header[2];
252             DT_M128A Legacy[8];
253             DT_M128A Xmm0;
254             DT_M128A Xmm1;
255             DT_M128A Xmm2;
256             DT_M128A Xmm3;
257             DT_M128A Xmm4;
258             DT_M128A Xmm5;
259             DT_M128A Xmm6;
260             DT_M128A Xmm7;
261             DT_M128A Xmm8;
262             DT_M128A Xmm9;
263             DT_M128A Xmm10;
264             DT_M128A Xmm11;
265             DT_M128A Xmm12;
266             DT_M128A Xmm13;
267             DT_M128A Xmm14;
268             DT_M128A Xmm15;
269         };
270     };
271
272     DT_M128A VectorRegister[26];
273     DWORD64 VectorControl;
274
275     DWORD64 DebugControl;
276     DWORD64 LastBranchToRip;
277     DWORD64 LastBranchFromRip;
278     DWORD64 LastExceptionToRip;
279     DWORD64 LastExceptionFromRip;
280 } DT_CONTEXT;
281
282 #elif defined(DTCONTEXT_IS_ARM)
283
284 #define DT_CONTEXT_ARM 0x00200000L
285
286 #define DT_CONTEXT_CONTROL         (DT_CONTEXT_ARM | 0x1L)
287 #define DT_CONTEXT_INTEGER         (DT_CONTEXT_ARM | 0x2L)
288 #define DT_CONTEXT_FLOATING_POINT  (DT_CONTEXT_ARM | 0x4L)
289 #define DT_CONTEXT_DEBUG_REGISTERS (DT_CONTEXT_ARM | 0x8L)
290
291 #define DT_CONTEXT_FULL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_FLOATING_POINT)
292 #define DT_CONTEXT_ALL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_DEBUG_REGISTERS)
293
294 #define DT_ARM_MAX_BREAKPOINTS     8
295 #define DT_ARM_MAX_WATCHPOINTS     1
296
297 typedef struct {
298     ULONGLONG Low;
299     LONGLONG High;
300 } DT_NEON128;
301
302 typedef DECLSPEC_ALIGN(8) struct {
303
304     //
305     // Control flags.
306     //
307
308     DWORD ContextFlags;
309
310     //
311     // Integer registers
312     //
313
314     DWORD R0;
315     DWORD R1;
316     DWORD R2;
317     DWORD R3;
318     DWORD R4;
319     DWORD R5;
320     DWORD R6;
321     DWORD R7;
322     DWORD R8;
323     DWORD R9;
324     DWORD R10;
325     DWORD R11;
326     DWORD R12;
327
328     //
329     // Control Registers
330     //
331
332     DWORD Sp;
333     DWORD Lr;
334     DWORD Pc;
335     DWORD Cpsr;
336
337     //
338     // Floating Point/NEON Registers
339     //
340
341     DWORD Fpscr;
342     DWORD Padding;
343     union {
344         DT_NEON128 Q[16];
345         ULONGLONG D[32];
346         DWORD S[32];
347     } DUMMYUNIONNAME;
348
349     //
350     // Debug registers
351     //
352
353     DWORD Bvr[DT_ARM_MAX_BREAKPOINTS];
354     DWORD Bcr[DT_ARM_MAX_BREAKPOINTS];
355     DWORD Wvr[DT_ARM_MAX_WATCHPOINTS];
356     DWORD Wcr[DT_ARM_MAX_WATCHPOINTS];
357
358     DWORD Padding2[2];
359
360 } DT_CONTEXT;
361
362 #elif defined(DTCONTEXT_IS_ARM64)
363
364 #define DT_CONTEXT_ARM64 0x00400000L
365
366 #define DT_CONTEXT_CONTROL         (DT_CONTEXT_ARM64 | 0x1L)
367 #define DT_CONTEXT_INTEGER         (DT_CONTEXT_ARM64 | 0x2L)
368 #define DT_CONTEXT_FLOATING_POINT  (DT_CONTEXT_ARM64 | 0x4L)
369 #define DT_CONTEXT_DEBUG_REGISTERS (DT_CONTEXT_ARM64 | 0x8L)
370
371 #define DT_CONTEXT_FULL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_FLOATING_POINT)
372 #define DT_CONTEXT_ALL (DT_CONTEXT_CONTROL | DT_CONTEXT_INTEGER | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_DEBUG_REGISTERS)
373
374 #define DT_ARM64_MAX_BREAKPOINTS     8
375 #define DT_ARM64_MAX_WATCHPOINTS     2
376
377 typedef struct {
378     ULONGLONG Low;
379     LONGLONG High;
380 } DT_NEON128;
381
382 typedef DECLSPEC_ALIGN(16) struct {
383     //
384     // Control flags.
385     //
386
387     /* +0x000 */ DWORD ContextFlags;
388
389     //
390     // Integer registers
391     //
392
393     /* +0x004 */ DWORD Cpsr;       // NZVF + DAIF + CurrentEL + SPSel
394     /* +0x008 */ union {
395                     struct {
396                         DWORD64 X0;
397                         DWORD64 X1;
398                         DWORD64 X2;
399                         DWORD64 X3;
400                         DWORD64 X4;
401                         DWORD64 X5;
402                         DWORD64 X6;
403                         DWORD64 X7;
404                         DWORD64 X8;
405                         DWORD64 X9;
406                         DWORD64 X10;
407                         DWORD64 X11;
408                         DWORD64 X12;
409                         DWORD64 X13;
410                         DWORD64 X14;
411                         DWORD64 X15;
412                         DWORD64 X16;
413                         DWORD64 X17;
414                         DWORD64 X18;
415                         DWORD64 X19;
416                         DWORD64 X20;
417                         DWORD64 X21;
418                         DWORD64 X22;
419                         DWORD64 X23;
420                         DWORD64 X24;
421                         DWORD64 X25;
422                         DWORD64 X26;
423                         DWORD64 X27;
424                         DWORD64 X28;
425                     };
426                     DWORD64 X[29];
427                  };
428     /* +0x0f0 */ DWORD64 Fp;
429     /* +0x0f8 */ DWORD64 Lr;
430     /* +0x100 */ DWORD64 Sp;
431     /* +0x108 */ DWORD64 Pc;
432
433     //
434     // Floating Point/NEON Registers
435     //
436
437     /* +0x110 */ DT_NEON128 V[32];
438     /* +0x310 */ DWORD Fpcr;
439     /* +0x314 */ DWORD Fpsr;
440
441     //
442     // Debug registers
443     //
444
445     /* +0x318 */ DWORD Bcr[DT_ARM64_MAX_BREAKPOINTS];
446     /* +0x338 */ DWORD64 Bvr[DT_ARM64_MAX_BREAKPOINTS];
447     /* +0x378 */ DWORD Wcr[DT_ARM64_MAX_WATCHPOINTS];
448     /* +0x380 */ DWORD64 Wvr[DT_ARM64_MAX_WATCHPOINTS];
449     /* +0x390 */
450
451 } DT_CONTEXT;
452
453 #else
454 #error Unsupported platform
455 #endif
456
457
458 #endif // __DBG_TARGET_CONTEXT_INCLUDED