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 | // |
7 | // LLDB debugger services for sos |
8 | // |
9 | //---------------------------------------------------------------------------- |
10 | |
11 | #ifndef __LLDBSERVICES_H__ |
12 | #define __LLDBSERVICES_H__ |
13 | |
14 | #include <stdarg.h> |
15 | #include <palrt.h> |
16 | #include <unknwn.h> |
17 | |
18 | #ifdef __cplusplus |
19 | extern "C" { |
20 | #endif |
21 | |
22 | // Output mask bits. |
23 | // Normal output. |
24 | #define DEBUG_OUTPUT_NORMAL 0x00000001 |
25 | // Error output. |
26 | #define DEBUG_OUTPUT_ERROR 0x00000002 |
27 | // Warnings. |
28 | #define DEBUG_OUTPUT_WARNING 0x00000004 |
29 | // Additional output. |
30 | #define DEBUG_OUTPUT_VERBOSE 0x00000008 |
31 | // Prompt output. |
32 | #define DEBUG_OUTPUT_PROMPT 0x00000010 |
33 | // Register dump before prompt. |
34 | #define DEBUG_OUTPUT_PROMPT_REGISTERS 0x00000020 |
35 | // Warnings specific to extension operation. |
36 | #define DEBUG_OUTPUT_EXTENSION_WARNING 0x00000040 |
37 | // Debuggee debug output, such as from OutputDebugString. |
38 | #define DEBUG_OUTPUT_DEBUGGEE 0x00000080 |
39 | // Debuggee-generated prompt, such as from DbgPrompt. |
40 | #define DEBUG_OUTPUT_DEBUGGEE_PROMPT 0x00000100 |
41 | // Symbol messages, such as for !sym noisy. |
42 | #define DEBUG_OUTPUT_SYMBOLS 0x00000200 |
43 | |
44 | // Execute and ExecuteCommandFile flags. |
45 | // These flags only apply to the command |
46 | // text itself; output from the executed |
47 | // command is controlled by the output |
48 | // control parameter. |
49 | // Default execution. Command is logged |
50 | // but not output. |
51 | #define DEBUG_EXECUTE_DEFAULT 0x00000000 |
52 | // Echo commands during execution. In |
53 | // ExecuteCommandFile also echoes the prompt |
54 | // for each line of the file. |
55 | #define DEBUG_EXECUTE_ECHO 0x00000001 |
56 | // Do not log or output commands during execution. |
57 | // Overridden by DEBUG_EXECUTE_ECHO. |
58 | #define DEBUG_EXECUTE_NOT_LOGGED 0x00000002 |
59 | // If this flag is not set an empty string |
60 | // to Execute will repeat the last Execute |
61 | // string. |
62 | #define DEBUG_EXECUTE_NO_REPEAT 0x00000004 |
63 | |
64 | // Classes of debuggee. Each class |
65 | // has different qualifiers for specific |
66 | // kinds of debuggees. |
67 | #define DEBUG_CLASS_UNINITIALIZED 0 |
68 | #define DEBUG_CLASS_KERNEL 1 |
69 | #define DEBUG_CLASS_USER_WINDOWS 2 |
70 | #define DEBUG_CLASS_IMAGE_FILE 3 |
71 | |
72 | // Generic dump types. These can be used |
73 | // with either user or kernel sessions. |
74 | // Session-type-specific aliases are also |
75 | // provided. |
76 | #define DEBUG_DUMP_SMALL 1024 |
77 | #define DEBUG_DUMP_DEFAULT 1025 |
78 | #define DEBUG_DUMP_FULL 1026 |
79 | #define DEBUG_DUMP_IMAGE_FILE 1027 |
80 | #define DEBUG_DUMP_TRACE_LOG 1028 |
81 | #define DEBUG_DUMP_WINDOWS_CE 1029 |
82 | |
83 | #define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. |
84 | #define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian |
85 | #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) |
86 | #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian |
87 | |
88 | // Execution status codes used for waiting, |
89 | // for returning current status and for |
90 | // event method return values. |
91 | #define DEBUG_STATUS_NO_CHANGE 0 |
92 | #define DEBUG_STATUS_GO 1 |
93 | #define DEBUG_STATUS_GO_HANDLED 2 |
94 | #define DEBUG_STATUS_GO_NOT_HANDLED 3 |
95 | #define DEBUG_STATUS_STEP_OVER 4 |
96 | #define DEBUG_STATUS_STEP_INTO 5 |
97 | #define DEBUG_STATUS_BREAK 6 |
98 | #define DEBUG_STATUS_NO_DEBUGGEE 7 |
99 | #define DEBUG_STATUS_STEP_BRANCH 8 |
100 | #define DEBUG_STATUS_IGNORE_EVENT 9 |
101 | #define DEBUG_STATUS_RESTART_REQUESTED 10 |
102 | #define DEBUG_STATUS_REVERSE_GO 11 |
103 | #define DEBUG_STATUS_REVERSE_STEP_BRANCH 12 |
104 | #define DEBUG_STATUS_REVERSE_STEP_OVER 13 |
105 | #define DEBUG_STATUS_REVERSE_STEP_INTO 14 |
106 | #define DEBUG_STATUS_OUT_OF_SYNC 15 |
107 | #define DEBUG_STATUS_WAIT_INPUT 16 |
108 | #define DEBUG_STATUS_TIMEOUT 17 |
109 | |
110 | #define DEBUG_STATUS_MASK 0x1f |
111 | |
112 | #define DEBUG_EVENT_EXCEPTION 0x00000002 |
113 | |
114 | typedef struct _DEBUG_LAST_EVENT_INFO_EXCEPTION |
115 | { |
116 | EXCEPTION_RECORD64 ExceptionRecord; |
117 | ULONG FirstChance; |
118 | } DEBUG_LAST_EVENT_INFO_EXCEPTION, *PDEBUG_LAST_EVENT_INFO_EXCEPTION; |
119 | |
120 | // |
121 | // Information about a module. |
122 | // |
123 | |
124 | // Flags. |
125 | #define DEBUG_MODULE_LOADED 0x00000000 |
126 | #define DEBUG_MODULE_UNLOADED 0x00000001 |
127 | #define DEBUG_MODULE_USER_MODE 0x00000002 |
128 | #define DEBUG_MODULE_EXPLICIT 0x00000008 |
129 | #define DEBUG_MODULE_SECONDARY 0x00000010 |
130 | #define DEBUG_MODULE_SYNTHETIC 0x00000020 |
131 | #define DEBUG_MODULE_SYM_BAD_CHECKSUM 0x00010000 |
132 | |
133 | // Symbol types. |
134 | #define DEBUG_SYMTYPE_NONE 0 |
135 | #define DEBUG_SYMTYPE_COFF 1 |
136 | #define DEBUG_SYMTYPE_CODEVIEW 2 |
137 | #define DEBUG_SYMTYPE_PDB 3 |
138 | #define DEBUG_SYMTYPE_EXPORT 4 |
139 | #define DEBUG_SYMTYPE_DEFERRED 5 |
140 | #define DEBUG_SYMTYPE_SYM 6 |
141 | #define DEBUG_SYMTYPE_DIA 7 |
142 | |
143 | typedef struct _DEBUG_MODULE_PARAMETERS |
144 | { |
145 | ULONG64 Base; |
146 | ULONG Size; |
147 | ULONG TimeDateStamp; |
148 | ULONG Checksum; |
149 | ULONG Flags; |
150 | ULONG SymbolType; |
151 | ULONG ImageNameSize; |
152 | ULONG ModuleNameSize; |
153 | ULONG LoadedImageNameSize; |
154 | ULONG SymbolFileNameSize; |
155 | ULONG MappedImageNameSize; |
156 | ULONG64 Reserved[2]; |
157 | } DEBUG_MODULE_PARAMETERS, *PDEBUG_MODULE_PARAMETERS; |
158 | |
159 | // FindSourceFile flags. |
160 | #define DEBUG_FIND_SOURCE_DEFAULT 0x00000000 |
161 | // Returns fully-qualified paths only. If this |
162 | // is not set the path returned may be relative. |
163 | #define DEBUG_FIND_SOURCE_FULL_PATH 0x00000001 |
164 | // Scans all the path elements for a match and |
165 | // returns the one that has the most similarity |
166 | // between the given file and the matching element. |
167 | #define DEBUG_FIND_SOURCE_BEST_MATCH 0x00000002 |
168 | // Do not search source server paths. |
169 | #define DEBUG_FIND_SOURCE_NO_SRCSRV 0x00000004 |
170 | // Restrict FindSourceFileAndToken to token lookup only. |
171 | #define DEBUG_FIND_SOURCE_TOKEN_LOOKUP 0x00000008 |
172 | |
173 | // A special value marking an offset that should not |
174 | // be treated as a valid offset. This is only used |
175 | // in special situations where it is unlikely that |
176 | // this value would be a valid offset. |
177 | #define DEBUG_INVALID_OFFSET ((ULONG64)-1) |
178 | |
179 | // General unspecified ID constant. |
180 | #define DEBUG_ANY_ID 0xffffffff |
181 | |
182 | typedef struct _DEBUG_STACK_FRAME |
183 | { |
184 | ULONG64 InstructionOffset; |
185 | ULONG64 ReturnOffset; |
186 | ULONG64 FrameOffset; |
187 | ULONG64 StackOffset; |
188 | ULONG64 FuncTableEntry; |
189 | ULONG64 Params[4]; |
190 | ULONG64 Reserved[6]; |
191 | BOOL Virtual; |
192 | ULONG ; |
193 | } DEBUG_STACK_FRAME, *PDEBUG_STACK_FRAME; |
194 | |
195 | #define DBG_FRAME_DEFAULT 0 // the same as INLINE_FRAME_CONTEXT_INIT in dbghelp.h |
196 | #define DBG_FRAME_IGNORE_INLINE 0xFFFFFFFF // the same as INLINE_FRAME_CONTEXT_IGNORE in dbghelp.h |
197 | |
198 | typedef struct _DEBUG_STACK_FRAME_EX |
199 | { |
200 | // First DEBUG_STACK_FRAME structure |
201 | ULONG64 InstructionOffset; |
202 | ULONG64 ReturnOffset; |
203 | ULONG64 FrameOffset; |
204 | ULONG64 StackOffset; |
205 | ULONG64 FuncTableEntry; |
206 | ULONG64 Params[4]; |
207 | ULONG64 Reserved[6]; |
208 | BOOL Virtual; |
209 | ULONG ; |
210 | |
211 | // Extended DEBUG_STACK_FRAME fields. |
212 | ULONG InlineFrameContext; |
213 | ULONG Reserved1; // For alignment purpose. |
214 | } DEBUG_STACK_FRAME_EX, *PDEBUG_STACK_FRAME_EX; |
215 | |
216 | // The types of inline frame context. |
217 | #define STACK_FRAME_TYPE_INIT 0x00 |
218 | #define STACK_FRAME_TYPE_STACK 0x01 |
219 | #define STACK_FRAME_TYPE_INLINE 0x02 |
220 | #define STACK_FRAME_TYPE_RA 0x80 // Whether the instruction pointer is the current IP or a RA from callee frame. |
221 | #define STACK_FRAME_TYPE_IGNORE 0xFF |
222 | |
223 | // |
224 | // options that are set/returned by SymSetOptions() & SymGetOptions() |
225 | // these are used as a mask |
226 | // |
227 | #define SYMOPT_LOAD_LINES 0x00000010 |
228 | |
229 | interface ILLDBServices; |
230 | typedef HRESULT (*PFN_EXCEPTION_CALLBACK)(ILLDBServices *services); |
231 | |
232 | //---------------------------------------------------------------------------- |
233 | // ILLDBServices |
234 | //---------------------------------------------------------------------------- |
235 | |
236 | MIDL_INTERFACE("2E6C569A-9E14-4DA4-9DFC-CDB73A532566" ) |
237 | ILLDBServices : public IUnknown |
238 | { |
239 | public: |
240 | //---------------------------------------------------------------------------- |
241 | // ILLDBServices |
242 | //---------------------------------------------------------------------------- |
243 | |
244 | // Returns the coreclr module directory found by lldb plugin |
245 | // in the target process. |
246 | virtual PCSTR GetCoreClrDirectory() = 0; |
247 | |
248 | // Evaluates a lldb expression into a value. |
249 | virtual DWORD_PTR GetExpression( |
250 | /* [in] */ PCSTR exp) = 0; |
251 | |
252 | // Unwind one native stack frame given a thread and register context |
253 | virtual HRESULT VirtualUnwind( |
254 | /* [in] */ DWORD threadID, |
255 | /* [in] */ ULONG32 contextSize, |
256 | /* [in, out, size_is(contextSize)] */ PBYTE context) = 0; |
257 | |
258 | // Set an exception throw callback |
259 | virtual HRESULT SetExceptionCallback( |
260 | /* [in] */ PFN_EXCEPTION_CALLBACK callback) = 0; |
261 | |
262 | // Clear the exception throw callback |
263 | virtual HRESULT ClearExceptionCallback() = 0; |
264 | |
265 | //------------------------------------------------ |
266 | // IDebugControl2 |
267 | //------------------------------------------------ |
268 | |
269 | // Checks for a user interrupt, such a Ctrl-C |
270 | // or stop button. |
271 | // This method is reentrant. |
272 | virtual HRESULT GetInterrupt( |
273 | void) = 0; |
274 | |
275 | virtual HRESULT OutputVaList( |
276 | ULONG mask, |
277 | PCSTR format, |
278 | va_list args) = 0; |
279 | |
280 | // Returns information about the debuggee such |
281 | // as user vs. kernel, dump vs. live, etc. |
282 | virtual HRESULT GetDebuggeeType( |
283 | PULONG debugClass, |
284 | PULONG qualifier) = 0; |
285 | |
286 | // Returns the page size for the currently executing |
287 | // processor context. The page size may vary between |
288 | // processor types. |
289 | virtual HRESULT GetPageSize( |
290 | PULONG size) = 0; |
291 | |
292 | // Returns the type of processor used in the |
293 | // current processor context. |
294 | virtual HRESULT GetExecutingProcessorType( |
295 | PULONG type) = 0; |
296 | |
297 | // Executes the given command string. |
298 | // If the string has multiple commands |
299 | // Execute will not return until all |
300 | // of them have been executed. If this |
301 | // requires waiting for the debuggee to |
302 | // execute an internal wait will be done |
303 | // so Execute can take an arbitrary amount |
304 | // of time. |
305 | virtual HRESULT Execute( |
306 | ULONG outputControl, |
307 | PCSTR command, |
308 | ULONG flags) = 0; |
309 | |
310 | // Retrieves information about the last event that occurred. |
311 | // EventType is one of the event callback mask bits. |
312 | // ExtraInformation contains additional event-specific |
313 | // information. Not all events have additional information. |
314 | virtual HRESULT GetLastEventInformation( |
315 | PULONG type, |
316 | PULONG processId, |
317 | PULONG threadId, |
318 | PVOID , |
319 | ULONG , |
320 | PULONG , |
321 | PSTR description, |
322 | ULONG descriptionSize, |
323 | PULONG descriptionUsed) = 0; |
324 | |
325 | virtual HRESULT Disassemble( |
326 | ULONG64 offset, |
327 | ULONG flags, |
328 | PSTR buffer, |
329 | ULONG bufferSize, |
330 | PULONG disassemblySize, |
331 | PULONG64 endOffset) = 0; |
332 | |
333 | //---------------------------------------------------------------------------- |
334 | // IDebugControl4 |
335 | //---------------------------------------------------------------------------- |
336 | |
337 | // Stack tracing with a full initial context |
338 | // and full context return for each frame. |
339 | // The FrameContextsSize parameter is the total |
340 | // byte size of FrameContexts. FrameContextsEntrySize |
341 | // gives the byte size of each entry in |
342 | // FrameContexts. |
343 | virtual HRESULT GetContextStackTrace( |
344 | PVOID startContext, |
345 | ULONG startContextSize, |
346 | PDEBUG_STACK_FRAME frames, |
347 | ULONG framesSize, |
348 | PVOID frameContexts, |
349 | ULONG frameContextsSize, |
350 | ULONG frameContextsEntrySize, |
351 | PULONG framesFilled) = 0; |
352 | |
353 | //------------------------------------------------ |
354 | // IDebugDataSpaces |
355 | //------------------------------------------------ |
356 | |
357 | virtual HRESULT ReadVirtual( |
358 | ULONG64 offset, |
359 | PVOID buffer, |
360 | ULONG bufferSize, |
361 | PULONG bytesRead) = 0; |
362 | |
363 | virtual HRESULT WriteVirtual( |
364 | ULONG64 offset, |
365 | PVOID buffer, |
366 | ULONG bufferSize, |
367 | PULONG bytesWritten) = 0; |
368 | |
369 | //------------------------------------------------ |
370 | // IDebugSymbols |
371 | //------------------------------------------------ |
372 | |
373 | // Controls the symbol options used during |
374 | // symbol operations. |
375 | // Uses the same flags as dbghelps SymSetOptions. |
376 | virtual HRESULT GetSymbolOptions( |
377 | PULONG options) = 0; |
378 | |
379 | virtual HRESULT GetNameByOffset( |
380 | ULONG64 offset, |
381 | PSTR nameBuffer, |
382 | ULONG nameBufferSize, |
383 | PULONG nameSize, |
384 | PULONG64 displacement) = 0; |
385 | |
386 | // Enumerates the engines list of modules |
387 | // loaded for the current process. This may |
388 | // or may not match the system module list |
389 | // for the process. Reload can be used to |
390 | // synchronize the engines list with the system |
391 | // if necessary. |
392 | // Some sessions also track recently unloaded |
393 | // code modules for help in analyzing failures |
394 | // where an attempt is made to call unloaded code. |
395 | // These modules are indexed after the loaded |
396 | // modules. |
397 | virtual HRESULT GetNumberModules( |
398 | PULONG loaded, |
399 | PULONG unloaded) = 0; |
400 | |
401 | virtual HRESULT GetModuleByIndex( |
402 | ULONG index, |
403 | PULONG64 base) = 0; |
404 | |
405 | // The module name may not be unique. |
406 | // This method returns the first match. |
407 | virtual HRESULT GetModuleByModuleName( |
408 | PCSTR name, |
409 | ULONG startIndex, |
410 | PULONG index, |
411 | PULONG64 base) = 0; |
412 | |
413 | // Offset can be any offset within |
414 | // the module extent. Extents may |
415 | // not be unique when including unloaded |
416 | // drivers. This method returns the |
417 | // first match. |
418 | virtual HRESULT GetModuleByOffset( |
419 | ULONG64 offset, |
420 | ULONG startIndex, |
421 | PULONG index, |
422 | PULONG64 base) = 0; |
423 | |
424 | // If Index is DEBUG_ANY_ID the base address |
425 | // is used to look up the module instead. |
426 | virtual HRESULT GetModuleNames( |
427 | ULONG index, |
428 | ULONG64 base, |
429 | PSTR imageNameBuffer, |
430 | ULONG imageNameBufferSize, |
431 | PULONG imageNameSize, |
432 | PSTR moduleNameBuffer, |
433 | ULONG moduleNameBufferSize, |
434 | PULONG moduleNameSize, |
435 | PSTR loadedImageNameBuffer, |
436 | ULONG loadedImageNameBufferSize, |
437 | PULONG loadedImageNameSize) = 0; |
438 | |
439 | HRESULT virtual GetLineByOffset( |
440 | ULONG64 offset, |
441 | PULONG line, |
442 | PSTR fileBuffer, |
443 | ULONG fileBufferSize, |
444 | PULONG fileSize, |
445 | PULONG64 displacement) = 0; |
446 | |
447 | HRESULT virtual GetSourceFileLineOffsets( |
448 | PCSTR file, |
449 | PULONG64 buffer, |
450 | ULONG bufferLines, |
451 | PULONG fileLines) = 0; |
452 | |
453 | // Uses the given file path and the source path |
454 | // information to try and locate an existing file. |
455 | // The given file path is merged with elements |
456 | // of the source path and checked for existence. |
457 | // If a match is found the element used is returned. |
458 | // A starting element can be specified to restrict |
459 | // the search to a subset of the path elements; |
460 | // this can be useful when checking for multiple |
461 | // matches along the source path. |
462 | // The returned element can be 1, indicating |
463 | // the file was found directly and not on the path. |
464 | HRESULT virtual FindSourceFile( |
465 | ULONG startElement, |
466 | PCSTR file, |
467 | ULONG flags, |
468 | PULONG foundElement, |
469 | PSTR buffer, |
470 | ULONG bufferSize, |
471 | PULONG foundSize) = 0; |
472 | |
473 | //------------------------------------------------ |
474 | // IDebugSystemObjects |
475 | //------------------------------------------------ |
476 | |
477 | virtual HRESULT GetCurrentProcessId( |
478 | PULONG id) = 0; |
479 | |
480 | // Controls implicit thread used by the |
481 | // debug engine. The debuggers current |
482 | // thread is just a piece of data held |
483 | // by the debugger for calls which use |
484 | // thread-specific information. In those |
485 | // calls the debuggers current thread is used. |
486 | // The debuggers current thread is not related |
487 | // to any system thread attribute. |
488 | // IDs for threads are small integer IDs |
489 | // maintained by the engine. They are not |
490 | // related to system thread IDs. |
491 | virtual HRESULT GetCurrentThreadId( |
492 | PULONG id) = 0; |
493 | |
494 | virtual HRESULT SetCurrentThreadId( |
495 | ULONG id) = 0; |
496 | |
497 | // Returns the system unique ID for the current thread. |
498 | // Not currently supported when kernel debugging. |
499 | virtual HRESULT GetCurrentThreadSystemId( |
500 | PULONG sysId) = 0; |
501 | |
502 | // Looks up a debugger thread ID for the given |
503 | // system thread ID. |
504 | // Currently when kernel debugging this will fail |
505 | // if the thread is not executing on a processor. |
506 | virtual HRESULT GetThreadIdBySystemId( |
507 | ULONG sysId, |
508 | PULONG id) = 0; |
509 | |
510 | // This is a special sos/lldb function used to implement the ICLRDataTarget interface and |
511 | // not actually part of dbgeng's IDebugSystemObjects interface. |
512 | virtual HRESULT GetThreadContextById( |
513 | /* [in] */ ULONG32 threadID, |
514 | /* [in] */ ULONG32 contextFlags, |
515 | /* [in] */ ULONG32 contextSize, |
516 | /* [out, size_is(contextSize)] */ PBYTE context) = 0; |
517 | |
518 | //------------------------------------------------ |
519 | // IDebugRegister |
520 | //------------------------------------------------ |
521 | |
522 | // This is the combination of dbgeng's GetIndexByName and GetValue and not |
523 | // actually part of the dbgeng's IDebugRegister interface. |
524 | virtual HRESULT GetValueByName( |
525 | PCSTR name, |
526 | PDWORD_PTR value) = 0; |
527 | |
528 | // Abstracted pieces of processor information. |
529 | // The mapping of these values to architectural |
530 | // registers is architecture-specific and their |
531 | // interpretation and existence may vary. They |
532 | // are intended to be directly compatible with |
533 | // calls which take this information, such as |
534 | // stack walking. |
535 | virtual HRESULT GetInstructionOffset( |
536 | PULONG64 offset) = 0; |
537 | |
538 | virtual HRESULT GetStackOffset( |
539 | PULONG64 offset) = 0; |
540 | |
541 | virtual HRESULT GetFrameOffset( |
542 | PULONG64 offset) = 0; |
543 | }; |
544 | |
545 | #ifdef __cplusplus |
546 | }; |
547 | #endif |
548 | |
549 | #endif // #ifndef __LLDBSERVICES_H__ |
550 | |