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 /**********************************************************************************/
6 // DebugInfo types shared by JIT-EE interface and EE-Debugger interface
7 
8 class ICorDebugInfo
9 {
10 public:
11     /*----------------------------- Boundary-info ---------------------------*/
12 
13     enum MappingTypes
14     {
15         NO_MAPPING  = -1,
16         PROLOG      = -2,
17         EPILOG      = -3,
18         MAX_MAPPING_VALUE = -3 // Sentinal value. This should be set to the largest magnitude value in the enum
19                                // so that the compression routines know the enum's range.
20     };
21 
22     enum BoundaryTypes
23     {
24         NO_BOUNDARIES           = 0x00,     // No implicit boundaries
25         STACK_EMPTY_BOUNDARIES  = 0x01,     // Boundary whenever the IL evaluation stack is empty
26         NOP_BOUNDARIES          = 0x02,     // Before every CEE_NOP instruction
27         CALL_SITE_BOUNDARIES    = 0x04,     // Before every CEE_CALL, CEE_CALLVIRT, etc instruction
28 
29         // Set of boundaries that debugger should always reasonably ask the JIT for.
30         DEFAULT_BOUNDARIES      = STACK_EMPTY_BOUNDARIES | NOP_BOUNDARIES | CALL_SITE_BOUNDARIES
31     };
32 
33     // Note that SourceTypes can be OR'd together - it's possible that
34     // a sequence point will also be a stack_empty point, and/or a call site.
35     // The debugger will check to see if a boundary offset's source field &
36     // SEQUENCE_POINT is true to determine if the boundary is a sequence point.
37 
38     enum SourceTypes
39     {
40         SOURCE_TYPE_INVALID        = 0x00, // To indicate that nothing else applies
41         SEQUENCE_POINT             = 0x01, // The debugger asked for it.
42         STACK_EMPTY                = 0x02, // The stack is empty here
43         CALL_SITE                  = 0x04, // This is a call site.
44         NATIVE_END_OFFSET_UNKNOWN  = 0x08, // Indicates a epilog endpoint
45         CALL_INSTRUCTION           = 0x10  // The actual instruction of a call.
46 
47     };
48 
49     struct OffsetMapping
50     {
51         DWORD           nativeOffset;
52         DWORD           ilOffset;
53         SourceTypes     source; // The debugger needs this so that
54                                 // we don't put Edit and Continue breakpoints where
55                                 // the stack isn't empty.  We can put regular breakpoints
56                                 // there, though, so we need a way to discriminate
57                                 // between offsets.
58     };
59 
60     /*------------------------------ Var-info -------------------------------*/
61 
62     // Note: The debugger needs to target register numbers on platforms other than which the debugger itself
63     // is running. To this end it maintains its own values for REGNUM_SP and REGNUM_AMBIENT_SP across multiple
64     // platforms. So any change here that may effect these values should be reflected in the definitions
65     // contained in debug/inc/DbgIPCEvents.h.
66     enum RegNum
67     {
68 #ifdef _TARGET_X86_
69         REGNUM_EAX,
70         REGNUM_ECX,
71         REGNUM_EDX,
72         REGNUM_EBX,
73         REGNUM_ESP,
74         REGNUM_EBP,
75         REGNUM_ESI,
76         REGNUM_EDI,
77 #elif _TARGET_ARM_
78         REGNUM_R0,
79         REGNUM_R1,
80         REGNUM_R2,
81         REGNUM_R3,
82         REGNUM_R4,
83         REGNUM_R5,
84         REGNUM_R6,
85         REGNUM_R7,
86         REGNUM_R8,
87         REGNUM_R9,
88         REGNUM_R10,
89         REGNUM_R11,
90         REGNUM_R12,
91         REGNUM_SP,
92         REGNUM_LR,
93         REGNUM_PC,
94 #elif _TARGET_ARM64_
95         REGNUM_X0,
96         REGNUM_X1,
97         REGNUM_X2,
98         REGNUM_X3,
99         REGNUM_X4,
100         REGNUM_X5,
101         REGNUM_X6,
102         REGNUM_X7,
103         REGNUM_X8,
104         REGNUM_X9,
105         REGNUM_X10,
106         REGNUM_X11,
107         REGNUM_X12,
108         REGNUM_X13,
109         REGNUM_X14,
110         REGNUM_X15,
111         REGNUM_X16,
112         REGNUM_X17,
113         REGNUM_X18,
114         REGNUM_X19,
115         REGNUM_X20,
116         REGNUM_X21,
117         REGNUM_X22,
118         REGNUM_X23,
119         REGNUM_X24,
120         REGNUM_X25,
121         REGNUM_X26,
122         REGNUM_X27,
123         REGNUM_X28,
124         REGNUM_FP,
125         REGNUM_LR,
126         REGNUM_SP,
127         REGNUM_PC,
128 #elif _TARGET_AMD64_
129         REGNUM_RAX,
130         REGNUM_RCX,
131         REGNUM_RDX,
132         REGNUM_RBX,
133         REGNUM_RSP,
134         REGNUM_RBP,
135         REGNUM_RSI,
136         REGNUM_RDI,
137         REGNUM_R8,
138         REGNUM_R9,
139         REGNUM_R10,
140         REGNUM_R11,
141         REGNUM_R12,
142         REGNUM_R13,
143         REGNUM_R14,
144         REGNUM_R15,
145 #else
146         PORTABILITY_WARNING("Register numbers not defined on this platform")
147 #endif
148         REGNUM_COUNT,
149         REGNUM_AMBIENT_SP, // ambient SP support. Ambient SP is the original SP in the non-BP based frame.
150                            // Ambient SP should not change even if there are push/pop operations in the method.
151 
152 #ifdef _TARGET_X86_
153         REGNUM_FP = REGNUM_EBP,
154         REGNUM_SP = REGNUM_ESP,
155 #elif _TARGET_AMD64_
156         REGNUM_SP = REGNUM_RSP,
157 #elif _TARGET_ARM_
158 #ifdef REDHAWK
159         REGNUM_FP = REGNUM_R7,
160 #else
161         REGNUM_FP = REGNUM_R11,
162 #endif //REDHAWK
163 #elif _TARGET_ARM64_
164         //Nothing to do here. FP is already alloted.
165 #else
166         // RegNum values should be properly defined for this platform
167         REGNUM_FP = 0,
168         REGNUM_SP = 1,
169 #endif
170 
171     };
172 
173     // VarLoc describes the location of a native variable.  Note that currently, VLT_REG_BYREF and VLT_STK_BYREF
174     // are only used for value types on X64.
175 
176     enum VarLocType
177     {
178         VLT_REG,        // variable is in a register
179         VLT_REG_BYREF,  // address of the variable is in a register
180         VLT_REG_FP,     // variable is in an fp register
181         VLT_STK,        // variable is on the stack (memory addressed relative to the frame-pointer)
182         VLT_STK_BYREF,  // address of the variable is on the stack (memory addressed relative to the frame-pointer)
183         VLT_REG_REG,    // variable lives in two registers
184         VLT_REG_STK,    // variable lives partly in a register and partly on the stack
185         VLT_STK_REG,    // reverse of VLT_REG_STK
186         VLT_STK2,       // variable lives in two slots on the stack
187         VLT_FPSTK,      // variable lives on the floating-point stack
188         VLT_FIXED_VA,   // variable is a fixed argument in a varargs function (relative to VARARGS_HANDLE)
189 
190         VLT_COUNT,
191         VLT_INVALID,
192     };
193 
194     struct VarLoc
195     {
196         VarLocType      vlType;
197 
198         union
199         {
200             // VLT_REG/VLT_REG_FP -- Any pointer-sized enregistered value (TYP_INT, TYP_REF, etc)
201             // eg. EAX
202             // VLT_REG_BYREF -- the specified register contains the address of the variable
203             // eg. [EAX]
204 
205             struct
206             {
207                 RegNum      vlrReg;
208             } vlReg;
209 
210             // VLT_STK -- Any 32 bit value which is on the stack
211             // eg. [ESP+0x20], or [EBP-0x28]
212             // VLT_STK_BYREF -- the specified stack location contains the address of the variable
213             // eg. mov EAX, [ESP+0x20]; [EAX]
214 
215             struct
216             {
217                 RegNum      vlsBaseReg;
218                 signed      vlsOffset;
219             } vlStk;
220 
221             // VLT_REG_REG -- TYP_LONG with both DWords enregistred
222             // eg. RBM_EAXEDX
223 
224             struct
225             {
226                 RegNum      vlrrReg1;
227                 RegNum      vlrrReg2;
228             } vlRegReg;
229 
230             // VLT_REG_STK -- Partly enregistered TYP_LONG
231             // eg { LowerDWord=EAX UpperDWord=[ESP+0x8] }
232 
233             struct
234             {
235                 RegNum      vlrsReg;
236                 struct
237                 {
238                     RegNum      vlrssBaseReg;
239                     signed      vlrssOffset;
240                 }           vlrsStk;
241             } vlRegStk;
242 
243             // VLT_STK_REG -- Partly enregistered TYP_LONG
244             // eg { LowerDWord=[ESP+0x8] UpperDWord=EAX }
245 
246             struct
247             {
248                 struct
249                 {
250                     RegNum      vlsrsBaseReg;
251                     signed      vlsrsOffset;
252                 }           vlsrStk;
253                 RegNum      vlsrReg;
254             } vlStkReg;
255 
256             // VLT_STK2 -- Any 64 bit value which is on the stack,
257             // in 2 successsive DWords.
258             // eg 2 DWords at [ESP+0x10]
259 
260             struct
261             {
262                 RegNum      vls2BaseReg;
263                 signed      vls2Offset;
264             } vlStk2;
265 
266             // VLT_FPSTK -- enregisterd TYP_DOUBLE (on the FP stack)
267             // eg. ST(3). Actually it is ST("FPstkHeigth - vpFpStk")
268 
269             struct
270             {
271                 unsigned        vlfReg;
272             } vlFPstk;
273 
274             // VLT_FIXED_VA -- fixed argument of a varargs function.
275             // The argument location depends on the size of the variable
276             // arguments (...). Inspecting the VARARGS_HANDLE indicates the
277             // location of the first arg. This argument can then be accessed
278             // relative to the position of the first arg
279 
280             struct
281             {
282                 unsigned        vlfvOffset;
283             } vlFixedVarArg;
284 
285             // VLT_MEMORY
286 
287             struct
288             {
289                 void        *rpValue; // pointer to the in-process
290                 // location of the value.
291             } vlMemory;
292         };
293     };
294 
295     // This is used to report implicit/hidden arguments
296 
297     enum
298     {
299         VARARGS_HND_ILNUM   = -1, // Value for the CORINFO_VARARGS_HANDLE varNumber
300         RETBUF_ILNUM        = -2, // Pointer to the return-buffer
301         TYPECTXT_ILNUM      = -3, // ParamTypeArg for CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
302 
303         UNKNOWN_ILNUM       = -4, // Unknown variable
304 
305         MAX_ILNUM           = -4  // Sentinal value. This should be set to the largest magnitude value in th enum
306                                   // so that the compression routines know the enum's range.
307     };
308 
309     struct ILVarInfo
310     {
311         DWORD           startOffset;
312         DWORD           endOffset;
313         DWORD           varNumber;
314     };
315 
316     struct NativeVarInfo
317     {
318         DWORD           startOffset;
319         DWORD           endOffset;
320         DWORD           varNumber;
321         VarLoc          loc;
322     };
323 };
324