ReactOS  0.4.15-dev-2704-gd5265b0
gdb_input.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: GPL, see COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: drivers/base/kddll/gdb_input.c
5  * PURPOSE: Base functions for the kernel debugger.
6  */
7 
8 #include "kdgdb.h"
9 
10 /* LOCALS *********************************************************************/
12 static struct
13 {
16 } BreakPointHandles[32];
17 
18 
19 /* GLOBALS ********************************************************************/
22 
23 static inline
26 {
27  return (x == KdPacketReceived) ? (KDSTATUS)-1 : x;
28 }
29 
30 /* PRIVATE FUNCTIONS **********************************************************/
31 static
34 {
35  ULONG_PTR ret = 0;
36  char hex;
37  while (*buffer)
38  {
39  hex = hex_value(*buffer++);
40  if (hex < 0)
41  return ret;
42  ret <<= 4;
43  ret += hex;
44  }
45  return ret;
46 }
47 #define hex_to_pid hex_to_tid
48 
49 static
50 ULONG64
52 {
53  ULONG64 ret = 0;
54  char hex;
55  while (*buffer)
56  {
57  hex = hex_value(*buffer++);
58  if (hex < 0)
59  return ret;
60  ret <<= 4;
61  ret += hex;
62  }
63  return ret;
64 }
65 
66 /* H* packets */
67 static
70 {
72 
73  switch (gdb_input[1])
74  {
75  case 'c':
76  if (strcmp(&gdb_input[2], "-1") == 0)
77  gdb_run_tid = (ULONG_PTR)-1;
78  else
80  Status = send_gdb_packet("OK");
81  break;
82  case 'g':
83  KDDBGPRINT("Setting debug thread: %s.\n", gdb_input);
84 #if MONOPROCESS
85  gdb_dbg_pid = 0;
86  if (strncmp(&gdb_input[2], "-1", 2) == 0)
87  {
88  gdb_dbg_tid = (UINT_PTR)-1;
89  }
90  else
91  {
93  }
94 #else
95  if (strncmp(&gdb_input[2], "p-1", 3) == 0)
96  {
97  gdb_dbg_pid = (UINT_PTR)-1;
98  gdb_dbg_tid = (UINT_PTR)-1;
99  }
100  else
101  {
102  char* ptr = strstr(gdb_input, ".") + 1;
104  if (strncmp(ptr, "-1", 2) == 0)
105  gdb_dbg_tid = (UINT_PTR)-1;
106  else
108  }
109 #endif
110  Status = send_gdb_packet("OK");
111  break;
112  default:
113  KDDBGPRINT("KDGBD: Unknown 'H' command: %s\n", gdb_input);
114  Status = send_gdb_packet("");
115  }
116 
117  return Status;
118 }
119 
120 static
121 KDSTATUS
123 {
124  ULONG_PTR Pid, Tid;
127 
128 #if MONOPROCESS
129  Pid = 0;
130  Tid = hex_to_tid(&gdb_input[1]);
131 
132  KDDBGPRINT("Checking if %p is alive.\n", Tid);
133 
134 #else
135  Pid = hex_to_pid(&gdb_input[2]);
136  Tid = hex_to_tid(strstr(gdb_input, ".") + 1);
137 
138  /* We cannot use PsLookupProcessThreadByCid as we could be running at any IRQL.
139  * So loop. */
140  KDDBGPRINT("Checking if p%p.%p is alive.\n", Pid, Tid);
141 #endif
142 
143  Thread = find_thread(Pid, Tid);
144 
145  if (Thread != NULL)
146  Status = send_gdb_packet("OK");
147  else
148  Status = send_gdb_packet("E03");
149 
150  return Status;
151 }
152 
153 /* q* packets */
154 static
155 KDSTATUS
157 {
158  if (strncmp(gdb_input, "qSupported:", 11) == 0)
159  {
160 #if MONOPROCESS
161  return send_gdb_packet("PacketSize=1000;qXfer:libraries:read+;");
162 #else
163  return send_gdb_packet("PacketSize=1000;multiprocess+;qXfer:libraries:read+;");
164 #endif
165  }
166 
167  if (strncmp(gdb_input, "qAttached", 9) == 0)
168  {
169 #if MONOPROCESS
170  return send_gdb_packet("1");
171 #else
172  UINT_PTR queried_pid = hex_to_pid(&gdb_input[10]);
173  /* Let's say we created system process */
174  if (gdb_pid_to_handle(queried_pid) == NULL)
175  return send_gdb_packet("0");
176  else
177  return send_gdb_packet("1");
178 #endif
179  }
180 
181  if (strncmp(gdb_input, "qRcmd,", 6) == 0)
182  {
183  return send_gdb_packet("OK");
184  }
185 
186  if (strcmp(gdb_input, "qC") == 0)
187  {
188  char gdb_out[64];
189 #if MONOPROCESS
190  sprintf(gdb_out, "QC:%"PRIxPTR";",
192 #else
193  sprintf(gdb_out, "QC:p%"PRIxPTR".%"PRIxPTR";",
196 #endif
197  return send_gdb_packet(gdb_out);
198  }
199 
200  if (strncmp(gdb_input, "qfThreadInfo", 12) == 0)
201  {
203  char gdb_out[40];
204  LIST_ENTRY* CurrentProcessEntry;
205 
206  CurrentProcessEntry = ProcessListHead->Flink;
207  if (CurrentProcessEntry == NULL) /* Ps is not initialized */
208  {
209 #if MONOPROCESS
210  return send_gdb_packet("m1");
211 #else
212  return send_gdb_packet("mp1.1");
213 #endif
214  }
215 
216  /* We will push threads as we find them */
218 
219  /* Start with the system thread */
220 #if MONOPROCESS
222 #else
223  send_gdb_partial_packet("mp1.1");
224 #endif
225 
226  /* List all the processes */
227  for ( ;
228  CurrentProcessEntry != ProcessListHead;
229  CurrentProcessEntry = CurrentProcessEntry->Flink)
230  {
231  LIST_ENTRY* CurrentThreadEntry;
232 
233  Process = CONTAINING_RECORD(CurrentProcessEntry, EPROCESS, ActiveProcessLinks);
234 
235  /* List threads from this process */
236  for ( CurrentThreadEntry = Process->ThreadListHead.Flink;
237  CurrentThreadEntry != &Process->ThreadListHead;
238  CurrentThreadEntry = CurrentThreadEntry->Flink)
239  {
240  PETHREAD Thread = CONTAINING_RECORD(CurrentThreadEntry, ETHREAD, ThreadListEntry);
241 
242 #if MONOPROCESS
243  _snprintf(gdb_out, 40, ",%p", handle_to_gdb_tid(Thread->Cid.UniqueThread));
244 #else
245  _snprintf(gdb_out, 40, ",p%p.%p",
246  handle_to_gdb_pid(Process->UniqueProcessId),
248 #endif
249  send_gdb_partial_packet(gdb_out);
250  }
251  }
252 
253  return finish_gdb_packet();
254  }
255 
256  if (strncmp(gdb_input, "qsThreadInfo", 12) == 0)
257  {
258  /* We sent the whole thread list on first qfThreadInfo call */
259  return send_gdb_packet("l");
260  }
261 
262  if (strncmp(gdb_input, "qGetTIBAddr:", 12) == 0)
263  {
264  ULONG_PTR Pid, Tid;
266 
267 #if MONOPROCESS
268  Pid = 0;
269  Tid = hex_to_tid(&gdb_input[12]);
270 
271  KDDBGPRINT(" %p.\n", Tid);
272 
273  Thread = find_thread(Pid, Tid);
274 #else
275  Pid = hex_to_pid(&gdb_input[13]);
276  Tid = hex_to_tid(strstr(&gdb_input[13], ".") + 1);
277 
278  /* We cannot use PsLookupProcessThreadByCid as we could be running at any IRQL.
279  * So loop. */
280  KDDBGPRINT(" p%p.%p.\n", Pid, Tid);
281  Thread = find_thread(Pid, Tid);
282 #endif
283  return send_gdb_memory(&Thread->Tcb.Teb, sizeof(Thread->Tcb.Teb));
284  }
285 
286  if (strncmp(gdb_input, "qThreadExtraInfo,", 17) == 0)
287  {
288  ULONG_PTR Pid, Tid;
291  char out_string[64];
292  STRING String = {0, 64, out_string};
293 
294  KDDBGPRINT("Giving extra info for");
295 
296 #if MONOPROCESS
297  Pid = 0;
298  Tid = hex_to_tid(&gdb_input[17]);
299 
300  KDDBGPRINT(" %p.\n", Tid);
301 
302  Thread = find_thread(Pid, Tid);
304 #else
305  Pid = hex_to_pid(&gdb_input[18]);
306  Tid = hex_to_tid(strstr(&gdb_input[18], ".") + 1);
307 
308  /* We cannot use PsLookupProcessThreadByCid as we could be running at any IRQL.
309  * So loop. */
310  KDDBGPRINT(" p%p.%p.\n", Pid, Tid);
311 
312  Process = find_process(Pid);
313  Thread = find_thread(Pid, Tid);
314 #endif
315 
316  if (PsGetThreadProcessId(Thread) == 0)
317  {
318  String.Length = sprintf(out_string, "SYSTEM");
319  }
320  else
321  {
322  String.Length = sprintf(out_string, "%.*s", 16, Process->ImageFileName);
323  }
324 
325  return gdb_send_debug_io(&String, FALSE);
326  }
327 
328  if (strcmp(gdb_input, "qTStatus") == 0)
329  {
330  /* No tracepoint support */
331  return send_gdb_packet("T0");
332  }
333 
334  if (strcmp(gdb_input, "qSymbol::") == 0)
335  {
336  /* No need */
337  return send_gdb_packet("OK");
338  }
339 
340  if (strncmp(gdb_input, "qXfer:libraries:read::", 22) == 0)
341  {
342  static LIST_ENTRY* CurrentEntry = NULL;
343  char str_helper[256];
344  char name_helper[64];
346  ULONG_PTR ToSend = hex_to_address(strstr(&gdb_input[22], ",") + 1);
347  ULONG Sent = 0;
348  static BOOLEAN allDone = FALSE;
349 
350  KDDBGPRINT("KDGDB: qXfer:libraries:read !\n");
351 
352  /* Start the packet */
354 
355  if (allDone)
356  {
358  allDone = FALSE;
359  return finish_gdb_packet();
360  }
361 
363  Sent++;
364 
365  /* Are we starting ? */
366  if (Offset == 0)
367  {
368  Sent += send_gdb_partial_binary("<?xml version=\"1.0\"?>", 21);
369  Sent += send_gdb_partial_binary("<library-list>", 14);
370 
371  CurrentEntry = ModuleListHead->Flink;
372 
373  if (!CurrentEntry)
374  {
375  /* Ps is not initialized. Send end of XML data or mark that we are finished. */
376  Sent += send_gdb_partial_binary("</library-list>", 15);
377  allDone = TRUE;
378  return finish_gdb_packet();
379  }
380  }
381 
382  for ( ;
383  CurrentEntry != ModuleListHead;
384  CurrentEntry = CurrentEntry->Flink)
385  {
386  PLDR_DATA_TABLE_ENTRY TableEntry = CONTAINING_RECORD(CurrentEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
387  PVOID DllBase = (PVOID)((ULONG_PTR)TableEntry->DllBase + 0x1000);
388  LONG mem_length;
389  USHORT i;
390 
391  /* Convert names to lower case. Yes this _is_ ugly */
392  for (i = 0; i < (TableEntry->BaseDllName.Length / sizeof(WCHAR)); i++)
393  {
394  name_helper[i] = (char)TableEntry->BaseDllName.Buffer[i];
395  if (name_helper[i] >= 'A' && name_helper[i] <= 'Z')
396  name_helper[i] += 'a' - 'A';
397  }
398  name_helper[i] = 0;
399 
400  /* GDB doesn't load the file if you don't prefix it with a drive letter... */
401  mem_length = _snprintf(str_helper, 256, "<library name=\"C:\\%s\"><segment address=\"0x%p\"/></library>", &name_helper, DllBase);
402 
403  /* DLL name must be too long. */
404  if (mem_length < 0)
405  {
406  KDDBGPRINT("Failed to report %wZ\n", &TableEntry->BaseDllName);
407  continue;
408  }
409 
410  if ((Sent + mem_length) > ToSend)
411  {
412  /* We're done for this pass */
413  return finish_gdb_packet();
414  }
415 
416  Sent += send_gdb_partial_binary(str_helper, mem_length);
417  }
418 
419  if ((ToSend - Sent) > 15)
420  {
421  Sent += send_gdb_partial_binary("</library-list>", 15);
422  allDone = TRUE;
423  }
424 
425  return finish_gdb_packet();
426  }
427 
428  KDDBGPRINT("KDGDB: Unknown query: %s\n", gdb_input);
429  return send_gdb_packet("");
430 }
431 
432 #if 0
433 static
434 KDSTATUS
435 handle_gdb_registers(
437  _Out_ PSTRING MessageData,
438  _Out_ PULONG MessageLength)
439 {
440  /*
441  if (gdb_dbg_thread)
442  KDDBGPRINT("Should get registers from other thread!\n");
443  */
444 
445  State->ApiNumber = DbgKdGetContextApi;
446  State->ReturnStatus = STATUS_SUCCESS; /* ? */
447  State->Processor = CurrentStateChange.Processor;
448  State->ProcessorLevel = CurrentStateChange.ProcessorLevel;
449  if (MessageData)
450  MessageData->Length = 0;
451  *MessageLength = 0;
452  return KdPacketReceived;
453 }
454 #endif
455 
456 static
457 BOOLEAN
459  _In_ ULONG PacketType,
460  _In_ PSTRING MessageHeader,
461  _In_ PSTRING MessageData)
462 {
463  DBGKD_MANIPULATE_STATE64* State = (DBGKD_MANIPULATE_STATE64*)MessageHeader->Buffer;
464 
465  if (PacketType != PACKET_TYPE_KD_STATE_MANIPULATE)
466  {
467  // KdAssert
468  KDDBGPRINT("Wrong packet type (%lu) received after DbgKdReadVirtualMemoryApi request.\n", PacketType);
469  return FALSE;
470  }
471 
472  if (State->ApiNumber != DbgKdReadVirtualMemoryApi)
473  {
474  KDDBGPRINT("Wrong API number (%lu) after DbgKdReadVirtualMemoryApi request.\n", State->ApiNumber);
475  return FALSE;
476  }
477 
478  /* Check status. Allow to send partial data. */
479  if (!MessageData->Length && !NT_SUCCESS(State->ReturnStatus))
480  send_gdb_ntstatus(State->ReturnStatus);
481  else
482  send_gdb_memory(MessageData->Buffer, MessageData->Length);
485 
486 #if MONOPROCESS
487  if (gdb_dbg_tid != 0)
488  /* Reset the TLB */
489 #else
491 #endif
492  {
493  /* Only do this if Ps is initialized */
494  if (ProcessListHead->Flink)
495  __writecr3(PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]);
496  }
497 
498  return TRUE;
499 }
500 
501 static
502 KDSTATUS
505  _Out_ PSTRING MessageData,
506  _Out_ PULONG MessageLength,
507  _Inout_ PKD_CONTEXT KdContext)
508 {
509  State->ApiNumber = DbgKdReadVirtualMemoryApi;
510  State->ReturnStatus = STATUS_SUCCESS; /* ? */
511  State->Processor = CurrentStateChange.Processor;
512  State->ProcessorLevel = CurrentStateChange.ProcessorLevel;
513  if (MessageData)
514  MessageData->Length = 0;
515  *MessageLength = 0;
516 
517  /* Set the TLB according to the process being read. Pid 0 means any process. */
518 #if MONOPROCESS
520  {
521  PETHREAD AttachedThread = find_thread(0, gdb_dbg_tid);
522  PKPROCESS AttachedProcess;
523  if (AttachedThread == NULL)
524  {
525  KDDBGPRINT("The current GDB debug thread is invalid!");
526  return LOOP_IF_SUCCESS(send_gdb_packet("E03"));
527  }
528 
529  AttachedProcess = AttachedThread->Tcb.Process;
530  if (AttachedProcess == NULL)
531  {
532  KDDBGPRINT("The current GDB debug thread is invalid!");
533  return LOOP_IF_SUCCESS(send_gdb_packet("E03"));
534  }
535  __writecr3(AttachedProcess->DirectoryTableBase[0]);
536  }
537 #else
539  {
540  PEPROCESS AttachedProcess = find_process(gdb_dbg_pid);
541  if (AttachedProcess == NULL)
542  {
543  KDDBGPRINT("The current GDB debug thread is invalid!");
544  return LOOP_IF_SUCCESS(send_gdb_packet("E03"));
545  }
546  /* Only do this if Ps is initialized */
547  if (ProcessListHead->Flink)
548  __writecr3(AttachedProcess->Pcb.DirectoryTableBase[0]);
549  }
550 #endif
551 
552  State->u.ReadMemory.TargetBaseAddress = hex_to_address(&gdb_input[1]);
553  State->u.ReadMemory.TransferCount = hex_to_address(strstr(&gdb_input[1], ",") + 1);
554 
555  /* KD will reply with KdSendPacket. Catch it */
557  return KdPacketReceived;
558 }
559 
560 static
561 BOOLEAN
563  _In_ ULONG PacketType,
564  _In_ PSTRING MessageHeader,
565  _In_ PSTRING MessageData)
566 {
567  DBGKD_MANIPULATE_STATE64* State = (DBGKD_MANIPULATE_STATE64*)MessageHeader->Buffer;
568 
569  if (PacketType != PACKET_TYPE_KD_STATE_MANIPULATE)
570  {
571  // KdAssert
572  KDDBGPRINT("Wrong packet type (%lu) received after DbgKdWriteVirtualMemoryApi request.\n", PacketType);
573  return FALSE;
574  }
575 
576  if (State->ApiNumber != DbgKdWriteVirtualMemoryApi)
577  {
578  KDDBGPRINT("Wrong API number (%lu) after DbgKdWriteVirtualMemoryApi request.\n", State->ApiNumber);
579  return FALSE;
580  }
581 
582  /* Check status */
583  if (!NT_SUCCESS(State->ReturnStatus))
584  send_gdb_ntstatus(State->ReturnStatus);
585  else
586  send_gdb_packet("OK");
589 
590 #if MONOPROCESS
591  if (gdb_dbg_tid != 0)
592  /* Reset the TLB */
593 #else
595 #endif
596  {
597  /* Only do this if Ps is initialized */
598  if (ProcessListHead->Flink)
599  __writecr3(PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]);
600  }
601  return TRUE;
602 }
603 
604 static
605 KDSTATUS
608  _Out_ PSTRING MessageData,
609  _Out_ PULONG MessageLength,
610  _Inout_ PKD_CONTEXT KdContext)
611 {
612  /* Maximal input buffer is 0x1000. Each byte is encoded on two bytes by GDB */
613  static UCHAR OutBuffer[0x800];
615  char* blob_ptr;
616  UCHAR* OutPtr;
617 
618  State->ApiNumber = DbgKdWriteVirtualMemoryApi;
619  State->ReturnStatus = STATUS_SUCCESS; /* ? */
620  State->Processor = CurrentStateChange.Processor;
621  State->ProcessorLevel = CurrentStateChange.ProcessorLevel;
622 
623  /* Set the TLB according to the process being read. Pid 0 means any process. */
624 #if MONOPROCESS
626  {
627  PETHREAD AttachedThread = find_thread(0, gdb_dbg_tid);
628  PKPROCESS AttachedProcess;
629  if (AttachedThread == NULL)
630  {
631  KDDBGPRINT("The current GDB debug thread is invalid!");
632  return LOOP_IF_SUCCESS(send_gdb_packet("E03"));
633  }
634 
635  AttachedProcess = AttachedThread->Tcb.Process;
636  if (AttachedProcess == NULL)
637  {
638  KDDBGPRINT("The current GDB debug thread is invalid!");
639  return LOOP_IF_SUCCESS(send_gdb_packet("E03"));
640  }
641  __writecr3(AttachedProcess->DirectoryTableBase[0]);
642  }
643 #else
645  {
646  PEPROCESS AttachedProcess = find_process(gdb_dbg_pid);
647  if (AttachedProcess == NULL)
648  {
649  KDDBGPRINT("The current GDB debug thread is invalid!");
650  return LOOP_IF_SUCCESS(send_gdb_packet("E03"));
651  }
652  /* Only do this if Ps is initialized */
653  if (ProcessListHead->Flink)
654  __writecr3(AttachedProcess->Pcb.DirectoryTableBase[0]);
655  }
656 #endif
657 
658  State->u.WriteMemory.TargetBaseAddress = hex_to_address(&gdb_input[1]);
659  BufferLength = hex_to_address(strstr(&gdb_input[1], ",") + 1);
660  if (BufferLength == 0)
661  {
662  /* Nothing to do */
663  return LOOP_IF_SUCCESS(send_gdb_packet("OK"));
664  }
665 
666  State->u.WriteMemory.TransferCount = BufferLength;
667  MessageData->Length = BufferLength;
668  MessageData->Buffer = (CHAR*)OutBuffer;
669 
670  OutPtr = OutBuffer;
671  blob_ptr = strstr(strstr(&gdb_input[1], ",") + 1, ":") + 1;
672  while (BufferLength)
673  {
674  if (BufferLength >= 4)
675  {
676  *((ULONG*)OutPtr) = *((ULONG*)blob_ptr);
677  OutPtr += 4;
678  blob_ptr += 4;
679  BufferLength -= 4;
680  }
681  else if (BufferLength >= 2)
682  {
683  *((USHORT*)OutPtr) = *((USHORT*)blob_ptr);
684  OutPtr += 2;
685  blob_ptr += 2;
686  BufferLength -= 2;
687  }
688  else
689  {
690  *OutPtr++ = *blob_ptr++;
691  BufferLength--;
692  }
693  }
694 
695  /* KD will reply with KdSendPacket. Catch it */
697  return KdPacketReceived;
698 }
699 
700 static
701 BOOLEAN
703  _In_ ULONG PacketType,
704  _In_ PSTRING MessageHeader,
705  _In_ PSTRING MessageData)
706 {
707  DBGKD_MANIPULATE_STATE64* State = (DBGKD_MANIPULATE_STATE64*)MessageHeader->Buffer;
708 
709  if (PacketType != PACKET_TYPE_KD_STATE_MANIPULATE)
710  {
711  // KdAssert
712  KDDBGPRINT("Wrong packet type (%lu) received after DbgKdWriteBreakPointApi request.\n", PacketType);
713  return FALSE;
714  }
715 
716  if (State->ApiNumber != DbgKdWriteBreakPointApi)
717  {
718  KDDBGPRINT("Wrong API number (%lu) after DbgKdWriteBreakPointApi request.\n", State->ApiNumber);
719  return FALSE;
720  }
721 
722  /* Check status */
723  if (!NT_SUCCESS(State->ReturnStatus))
724  {
725  KDDBGPRINT("Inserting breakpoint failed!\n");
726  send_gdb_ntstatus(State->ReturnStatus);
727  }
728  else
729  {
730  /* Keep track of the address+handle couple */
731  ULONG i;
732  for (i = 0; i < (sizeof(BreakPointHandles) / sizeof(BreakPointHandles[0])); i++)
733  {
734  if (BreakPointHandles[i].Address == 0)
735  {
736  BreakPointHandles[i].Address = (ULONG_PTR)State->u.WriteBreakPoint.BreakPointAddress;
737  BreakPointHandles[i].Handle = State->u.WriteBreakPoint.BreakPointHandle;
738  break;
739  }
740  }
741  send_gdb_packet("OK");
742  }
745  return TRUE;
746 }
747 
748 static
749 KDSTATUS
752  _Out_ PSTRING MessageData,
753  _Out_ PULONG MessageLength,
754  _Inout_ PKD_CONTEXT KdContext)
755 {
756  State->ReturnStatus = STATUS_SUCCESS; /* ? */
757  State->Processor = CurrentStateChange.Processor;
758  State->ProcessorLevel = CurrentStateChange.ProcessorLevel;
759  if (MessageData)
760  MessageData->Length = 0;
761  *MessageLength = 0;
762 
763  switch (gdb_input[1])
764  {
765  case '0':
766  {
768  ULONG i;
769  BOOLEAN HasFreeSlot = FALSE;
770 
771  KDDBGPRINT("Inserting breakpoint at %p.\n", (void*)Address);
772 
773  for (i = 0; i < (sizeof(BreakPointHandles) / sizeof(BreakPointHandles[0])); i++)
774  {
775  if (BreakPointHandles[i].Address == 0)
776  HasFreeSlot = TRUE;
777  }
778 
779  if (!HasFreeSlot)
780  {
781  /* We don't have a way to keep track of this break point. Fail. */
782  KDDBGPRINT("No breakpoint slot available!\n");
783  return LOOP_IF_SUCCESS(send_gdb_packet("E01"));
784  }
785 
786  State->ApiNumber = DbgKdWriteBreakPointApi;
787  State->u.WriteBreakPoint.BreakPointAddress = Address;
788  /* FIXME : ignoring all other Z0 arguments */
789 
790  /* KD will reply with KdSendPacket. Catch it */
792  return KdPacketReceived;
793  }
794  }
795 
796  KDDBGPRINT("Unhandled 'Z' packet: %s\n", gdb_input);
797  return LOOP_IF_SUCCESS(send_gdb_packet("E01"));
798 }
799 
800 static
801 BOOLEAN
803  _In_ ULONG PacketType,
804  _In_ PSTRING MessageHeader,
805  _In_ PSTRING MessageData)
806 {
807  DBGKD_MANIPULATE_STATE64* State = (DBGKD_MANIPULATE_STATE64*)MessageHeader->Buffer;
808  ULONG i;
809 
810  if (PacketType != PACKET_TYPE_KD_STATE_MANIPULATE)
811  {
812  // KdAssert
813  KDDBGPRINT("Wrong packet type (%lu) received after DbgKdRestoreBreakPointApi request.\n", PacketType);
814  return FALSE;
815  }
816 
817  if (State->ApiNumber != DbgKdRestoreBreakPointApi)
818  {
819  KDDBGPRINT("Wrong API number (%lu) after DbgKdRestoreBreakPointApi request.\n", State->ApiNumber);
820  return FALSE;
821  }
822 
823  /* We ignore failure here. If DbgKdRestoreBreakPointApi fails,
824  * this means that the breakpoint was already invalid for KD. So clean it up on our side. */
825  for (i = 0; i < (sizeof(BreakPointHandles) / sizeof(BreakPointHandles[0])); i++)
826  {
827  if (BreakPointHandles[i].Handle == State->u.RestoreBreakPoint.BreakPointHandle)
828  {
829  BreakPointHandles[i].Address = 0;
830  BreakPointHandles[i].Handle = 0;
831  break;
832  }
833  }
834 
835  send_gdb_packet("OK");
836 
839  return TRUE;
840 }
841 
842 static
843 KDSTATUS
846  _Out_ PSTRING MessageData,
847  _Out_ PULONG MessageLength,
848  _Inout_ PKD_CONTEXT KdContext)
849 {
850  State->ReturnStatus = STATUS_SUCCESS; /* ? */
851  State->Processor = CurrentStateChange.Processor;
852  State->ProcessorLevel = CurrentStateChange.ProcessorLevel;
853  if (MessageData)
854  MessageData->Length = 0;
855  *MessageLength = 0;
856 
857  switch (gdb_input[1])
858  {
859  case '0':
860  {
862  ULONG i, Handle = 0;
863 
864  KDDBGPRINT("Removing breakpoint on %p.\n", (void*)Address);
865 
866  for (i = 0; i < (sizeof(BreakPointHandles) / sizeof(BreakPointHandles[0])); i++)
867  {
869  {
870  Handle = BreakPointHandles[i].Handle;
871  break;
872  }
873  }
874 
875  if (Handle == 0)
876  {
877  KDDBGPRINT("Received %s, but breakpoint was never inserted ?!\n", gdb_input);
878  return LOOP_IF_SUCCESS(send_gdb_packet("E01"));
879  }
880 
881  State->ApiNumber = DbgKdRestoreBreakPointApi;
882  State->u.RestoreBreakPoint.BreakPointHandle = Handle;
883  /* FIXME : ignoring all other z0 arguments */
884 
885  /* KD will reply with KdSendPacket. Catch it */
887  return KdPacketReceived;
888  }
889  }
890 
891  KDDBGPRINT("Unhandled 'Z' packet: %s\n", gdb_input);
892  return LOOP_IF_SUCCESS(send_gdb_packet("E01"));
893 }
894 
895 static
896 KDSTATUS
899  _Out_ PSTRING MessageData,
900  _Out_ PULONG MessageLength,
901  _Inout_ PKD_CONTEXT KdContext)
902 {
904 
905  /* Tell GDB everything is fine, we will handle it */
906  Status = send_gdb_packet("OK");
907  if (Status != KdPacketReceived)
908  return Status;
909 
910 
912  {
914  ULONG_PTR ProgramCounter = KdpGetContextPc(&CurrentContext);
915 
916  /* See if we should update the program counter */
917  if (Exception && (Exception->ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT)
918  && ((*(KD_BREAKPOINT_TYPE*)ProgramCounter) == KD_BREAKPOINT_VALUE))
919  {
920  /* We must get past the breakpoint instruction */
921  KdpSetContextPc(&CurrentContext, ProgramCounter + KD_BREAKPOINT_SIZE);
922 
923  SetContextManipulateHandler(State, MessageData, MessageLength, KdContext);
925  return KdPacketReceived;
926  }
927  }
928 
929  return ContinueManipulateStateHandler(State, MessageData, MessageLength, KdContext);
930 }
931 
932 static
933 KDSTATUS
936  _Out_ PSTRING MessageData,
937  _Out_ PULONG MessageLength,
938  _Inout_ PKD_CONTEXT KdContext)
939 {
941 
942  /* Tell GDB everything is fine, we will handle it */
943  Status = send_gdb_packet("OK");
944  if (Status != KdPacketReceived)
945  return Status;
946 
948  {
949  /* Debugger didn't handle the exception, report it back to the kernel */
950  State->u.Continue2.ContinueStatus = CurrentStateChange.u.Exception.ExceptionRecord.ExceptionCode;
951  State->ApiNumber = DbgKdContinueApi2;
952  return KdPacketReceived;
953  }
954  /* We should never reach this ? */
955  return ContinueManipulateStateHandler(State, MessageData, MessageLength, KdContext);
956 }
957 
958 static
959 KDSTATUS
962  _Out_ PSTRING MessageData,
963  _Out_ PULONG MessageLength,
964  _Inout_ PKD_CONTEXT KdContext)
965 {
966  KDDBGPRINT("Single stepping.\n");
967  /* Set CPU single step mode and continue */
968  KdpSetSingleStep(&CurrentContext);
969  SetContextManipulateHandler(State, MessageData, MessageLength, KdContext);
971  return KdPacketReceived;
972 }
973 
974 static
975 KDSTATUS
978  _Out_ PSTRING MessageData,
979  _Out_ PULONG MessageLength,
980  _Inout_ PKD_CONTEXT KdContext)
981 {
982  if (strncmp(gdb_input, "vCont", 5) == 0)
983  {
984  if (gdb_input[5] == '?')
985  {
986  /* Report what we support */
987  return LOOP_IF_SUCCESS(send_gdb_packet("vCont;c;s"));
988  }
989 
990  if (strncmp(gdb_input, "vCont;c", 7) == 0)
991  {
992  return handle_gdb_c(State, MessageData, MessageLength, KdContext);
993  }
994 
995  if (strncmp(gdb_input, "vCont;s", 7) == 0)
996  {
997 
998  return handle_gdb_s(State, MessageData, MessageLength, KdContext);
999  }
1000  }
1001 
1002  KDDBGPRINT("Unhandled 'v' packet: %s\n", gdb_input);
1003  return LOOP_IF_SUCCESS(send_gdb_packet(""));
1004 }
1005 
1006 KDSTATUS
1009  _Out_ PSTRING MessageData,
1010  _Out_ PULONG MessageLength,
1011  _Inout_ PKD_CONTEXT KdContext)
1012 {
1013  KDSTATUS Status;
1014 
1015  do
1016  {
1017  KDDBGPRINT("KDGBD: Receiving packet.\n");
1018  Status = gdb_receive_packet(KdContext);
1019  KDDBGPRINT("KDGBD: Packet \"%s\" received with status %u\n", gdb_input, Status);
1020 
1021  if (Status != KdPacketReceived)
1022  return Status;
1023 
1024  Status = (KDSTATUS)-1;
1025 
1026  switch (gdb_input[0])
1027  {
1028  case '?':
1029  /* Send the Status */
1031  break;
1032  case '!':
1034  break;
1035  case 'c':
1036  Status = handle_gdb_c(State, MessageData, MessageLength, KdContext);
1037  break;
1038  case 'C':
1039  Status = handle_gdb_C(State, MessageData, MessageLength, KdContext);
1040  break;
1041  case 'g':
1043  break;
1044  case 'H':
1046  break;
1047  case 'm':
1048  Status = handle_gdb_read_mem(State, MessageData, MessageLength, KdContext);
1049  break;
1050  case 'p':
1052  break;
1053  case 'q':
1055  break;
1056  case 's':
1057  Status = handle_gdb_s(State, MessageData, MessageLength, KdContext);
1058  break;
1059  case 'T':
1061  break;
1062  case 'v':
1063  Status = handle_gdb_v(State, MessageData, MessageLength, KdContext);
1064  break;
1065  case 'X':
1066  Status = handle_gdb_write_mem(State, MessageData, MessageLength, KdContext);
1067  break;
1068  case 'z':
1069  Status = handle_gdb_remove_breakpoint(State, MessageData, MessageLength, KdContext);
1070  break;
1071  case 'Z':
1072  Status = handle_gdb_insert_breakpoint(State, MessageData, MessageLength, KdContext);
1073  break;
1074  default:
1075  /* We don't know how to handle this request. */
1076  KDDBGPRINT("Unsupported GDB command: %s.\n", gdb_input);
1078  }
1079  } while (Status == (KDSTATUS)-1);
1080 
1081  return Status;
1082 }
1083 
void send_gdb_partial_packet(_In_ const CHAR *Buffer)
Definition: gdb_send.c:60
#define KdPacketReceived
Definition: kddll.h:5
unsigned __int3264 UINT_PTR
Definition: activex.cpp:275
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
#define DbgKdWriteVirtualMemoryApi
Definition: windbgkd.h:75
FORCEINLINE HANDLE gdb_tid_to_handle(UINT_PTR Tid)
Definition: kdgdb.h:35
void send_gdb_ntstatus(_In_ NTSTATUS Status)
Definition: gdb_send.c:231
_In_ UCHAR _In_ ULONG _Out_ PUCHAR _Outptr_result_bytebuffer_ OutBufferLength PVOID * OutBuffer
Definition: scsi.h:4071
ULONG_PTR DirectoryTableBase
Definition: ketypes.h:2019
CONTEXT CurrentContext
Definition: kdpacket.c:29
#define KDDBGPRINT(...)
Definition: kddll.h:19
#define TRUE
Definition: types.h:120
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define DbgKdReadVirtualMemoryApi
Definition: windbgkd.h:74
char CHAR
Definition: xmlstorage.h:175
#define handle_to_gdb_pid
Definition: kdgdb.h:45
KTHREAD Tcb
Definition: pstypes.h:1103
NTSTATUS ExceptionCode
Definition: rtltypes.h:190
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static ULONG64 hex_to_address(char *buffer)
Definition: gdb_input.c:51
KDSTATUS ContinueManipulateStateHandler(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: kdpacket.c:213
#define DbgKdExceptionStateChange
Definition: windbgkd.h:59
static KDSTATUS handle_gdb_thread_alive(void)
Definition: gdb_input.c:122
KDP_MANIPULATESTATE_HANDLER KdpManipulateStateHandler
Definition: kdpacket.c:26
if(dx==0 &&dy==0)
Definition: linetemp.h:174
PKPROCESS Process
Definition: ketypes.h:1840
static KDSTATUS LOOP_IF_SUCCESS(int x)
Definition: gdb_input.c:25
static const char hex[16]
Definition: profile.c:123
#define DbgKdRestoreBreakPointApi
Definition: windbgkd.h:79
KDSTATUS send_gdb_memory(_In_ const VOID *Buffer, _In_ size_t Length)
Definition: gdb_send.c:158
DBGKD_ANY_WAIT_STATE_CHANGE CurrentStateChange
Definition: kdpacket.c:28
KDSTATUS send_gdb_packet(_In_ const CHAR *Buffer)
Definition: gdb_send.c:100
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define KD_BREAKPOINT_VALUE
Definition: ke.h:119
KDSTATUS gdb_send_exception()
Definition: gdb_send.c:197
#define sprintf(buf, format,...)
Definition: sprintf.c:55
ULONG Handle
Definition: gdb_input.c:15
#define _snprintf
Definition: xmlstorage.h:200
__INTRIN_INLINE void __writecr3(unsigned int Data)
Definition: intrin_x86.h:1795
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
#define FALSE
Definition: types.h:117
KDSTATUS gdb_receive_and_interpret_packet(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:1007
long LONG
Definition: pedump.c:60
static PVOID ptr
Definition: dispmode.c:27
static BOOLEAN RestoreBreakPointSendHandler(_In_ ULONG PacketType, _In_ PSTRING MessageHeader, _In_ PSTRING MessageData)
Definition: gdb_input.c:802
#define PsGetCurrentProcess
Definition: psfuncs.h:17
KDP_SEND_HANDLER KdpSendPacketHandler
Definition: kdpacket.c:25
unsigned char BOOLEAN
static KDSTATUS handle_gdb_remove_breakpoint(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:844
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
unsigned char
Definition: typeof.h:29
#define _Out_
Definition: no_sal2.h:160
PETHREAD find_thread(_In_ UINT_PTR Pid, _In_ UINT_PTR Tid)
Definition: utils.c:41
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
static BOOLEAN ReadMemorySendHandler(_In_ ULONG PacketType, _In_ PSTRING MessageHeader, _In_ PSTRING MessageData)
Definition: gdb_input.c:458
KDSTATUS gdb_send_registers(void)
Definition: amd64_sup.c:144
void * PVOID
Definition: retypes.h:9
static KDSTATUS handle_gdb_read_mem(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:503
static KDSTATUS handle_gdb_insert_breakpoint(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:750
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
char hex_value(char ch)
Definition: gdb_receive.c:15
KDSTATUS gdb_send_debug_io(_In_ PSTRING String, _In_ BOOLEAN WithPrefix)
Definition: gdb_send.c:168
KDSTATUS NTAPI gdb_receive_packet(_Inout_ PKD_CONTEXT KdContext)
Definition: gdb_receive.c:31
Status
Definition: gdiplustypes.h:24
UINT_PTR gdb_dbg_tid
Definition: gdb_input.c:21
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
void start_gdb_packet(void)
Definition: gdb_send.c:52
UINT_PTR gdb_dbg_pid
Definition: gdb_input.c:20
static KDSTATUS handle_gdb_write_mem(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:606
ULONG send_gdb_partial_binary(_In_ const VOID *Buffer, _In_ size_t Length)
Definition: gdb_send.c:108
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CLIENT_ID Cid
Definition: pstypes.h:1128
HANDLE NTAPI PsGetThreadProcessId(IN PETHREAD Thread)
Definition: thread.c:745
#define DbgKdGetContextApi
Definition: windbgkd.h:76
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
static BOOLEAN WriteMemorySendHandler(_In_ ULONG PacketType, _In_ PSTRING MessageHeader, _In_ PSTRING MessageData)
Definition: gdb_input.c:562
#define _Inout_
Definition: no_sal2.h:162
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
static UINT_PTR hex_to_tid(char *buffer)
Definition: gdb_input.c:33
HANDLE UniqueThread
Definition: compat.h:685
std::wstring STRING
Definition: fontsub.cpp:33
#define PACKET_TYPE_KD_STATE_MANIPULATE
Definition: windbgkd.h:43
unsigned __int64 ULONG64
Definition: imports.h:198
EXCEPTION_RECORD64 ExceptionRecord
Definition: windbgkd.h:303
unsigned char UCHAR
Definition: xmlstorage.h:181
static KDSTATUS handle_gdb_c(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:897
int ret
#define PRIxPTR
Definition: inttypes.h:236
#define hex_to_pid
Definition: gdb_input.c:47
PEPROCESS find_process(_In_ UINT_PTR Pid)
Definition: utils.c:16
Definition: btrfs_drv.h:1922
#define DbgKdContinueApi2
Definition: windbgkd.h:86
Definition: typedefs.h:119
static BOOLEAN WriteBreakPointSendHandler(_In_ ULONG PacketType, _In_ PSTRING MessageHeader, _In_ PSTRING MessageData)
Definition: gdb_input.c:702
KPROCESS Pcb
Definition: pstypes.h:1262
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
static KDSTATUS handle_gdb_set_thread(void)
Definition: gdb_input.c:69
KDSTATUS SetContextManipulateHandler(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: kdpacket.c:107
#define KD_BREAKPOINT_TYPE
Definition: ke.h:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define _In_
Definition: no_sal2.h:158
LIST_ENTRY * ProcessListHead
Definition: kdpacket.c:22
union _DBGKD_ANY_WAIT_STATE_CHANGE::@3504 u
#define DbgKdWriteBreakPointApi
Definition: windbgkd.h:78
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned short USHORT
Definition: pedump.c:61
ULONG KDSTATUS
Definition: kddll.h:4
unsigned int * PULONG
Definition: retypes.h:1
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define NULL
Definition: types.h:112
UINT Sent
Definition: arping.c:39
static ULONG_PTR gdb_run_tid
Definition: gdb_input.c:11
DBGKM_EXCEPTION64 Exception
Definition: windbgkd.h:488
PVOID Teb
Definition: ketypes.h:1739
static KDSTATUS handle_gdb_v(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:976
_Must_inspect_result_ typedef _In_ ULONG TableEntry
Definition: iotypes.h:4303
static KDSTATUS handle_gdb_s(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:960
static KDSTATUS handle_gdb_C(_Out_ DBGKD_MANIPULATE_STATE64 *State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext)
Definition: gdb_input.c:934
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
_In_ HANDLE Handle
Definition: extypes.h:390
FORCEINLINE UINT_PTR handle_to_gdb_tid(HANDLE Handle)
Definition: kdgdb.h:41
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ULONG_PTR Address
Definition: gdb_input.c:14
static struct @587 BreakPointHandles[32]
#define ULONG_PTR
Definition: config.h:101
CHAR gdb_input[0x1000]
Definition: gdb_receive.c:11
#define KD_BREAKPOINT_SIZE
Definition: ke.h:118
#define STATUS_SUCCESS
Definition: shellext.h:65
#define gdb_pid_to_handle
Definition: kdgdb.h:39
static KDSTATUS handle_gdb_query(void)
Definition: gdb_input.c:156
LIST_ENTRY * ModuleListHead
Definition: kdpacket.c:23
KDSTATUS finish_gdb_packet(void)
Definition: gdb_send.c:74
KDSTATUS gdb_send_register(void)
Definition: amd64_sup.c:219