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