ReactOS  0.4.14-dev-293-g2b39b42
gdb_send.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_send.c
5  * PURPOSE: Base functions for the kernel debugger.
6  */
7 
8 #include "kdgdb.h"
9 
10 /* LOCALS *********************************************************************/
11 const char hex_chars[] = "0123456789abcdef";
12 static CHAR currentChecksum = 0;
13 
14 /* PRIVATE FUNCTIONS **********************************************************/
15 static
16 char*
18 {
19  unsigned char SigVal;
20 
21  switch (code)
22  {
24  SigVal = 8; /* divide by zero */
25  break;
26  case STATUS_SINGLE_STEP:
27  case STATUS_BREAKPOINT:
28  SigVal = 5; /* breakpoint */
29  break;
32  SigVal = 16; /* bound instruction */
33  break;
35  SigVal = 4; /* Invalid opcode */
36  break;
40  SigVal = 11; /* access violation */
41  break;
42  default:
43  SigVal = 7; /* "software generated" */
44  }
45  *out++ = hex_chars[(SigVal >> 4) & 0xf];
46  *out++ = hex_chars[SigVal & 0xf];
47  return out;
48 }
49 
50 /* GLOBAL FUNCTIONS ***********************************************************/
51 void
53 {
54  /* Start the start byte and begin checksum calculation */
55  KdpSendByte('$');
56  currentChecksum = 0;
57 }
58 
59 void
61 {
62  const CHAR* ptr = Buffer;
63 
64  /* Update check sum and send */
65  while (*ptr)
66  {
67  currentChecksum += *ptr;
68  KdpSendByte(*ptr++);
69  }
70 }
71 
72 
75 {
76  UCHAR ack;
78 
79  /* Send finish byte and append checksum */
80  KdpSendByte('#');
81  KdpSendByte(hex_chars[(currentChecksum >> 4) & 0xf]);
83 
84  /* Wait for acknowledgement */
85  Status = KdpReceiveByte(&ack);
86 
87  if (Status != KdPacketReceived)
88  {
90  return Status;
91  }
92 
93  if (ack != '+')
94  return KdPacketNeedsResend;
95 
96  return KdPacketReceived;
97 }
98 
101 {
104  return finish_gdb_packet();
105 }
106 
107 ULONG
109  _In_ const VOID* Buffer,
110  _In_ size_t Length)
111 {
112  const UCHAR* ptr = Buffer;
113  ULONG Sent = Length;
114 
115  while(Length--)
116  {
117  UCHAR Byte = *ptr++;
118 
119  switch (Byte)
120  {
121  case 0x7d:
122  case 0x23:
123  case 0x24:
124  case 0x2a:
125  currentChecksum += 0x7d;
126  KdpSendByte(0x7d);
127  Byte ^= 0x20;
128  Sent++;
129  /* Fall-through */
130  default:
132  KdpSendByte(Byte);
133  }
134  }
135 
136  return Sent;
137 }
138 
139 void
141  _In_ const VOID* Buffer,
142  _In_ size_t Length)
143 {
144  const UCHAR* ptr = Buffer;
145  CHAR gdb_out[3];
146 
147  gdb_out[2] = '\0';
148 
149  while(Length--)
150  {
151  gdb_out[0] = hex_chars[(*ptr >> 4) & 0xf];
152  gdb_out[1] = hex_chars[*ptr++ & 0xf];
153  send_gdb_partial_packet(gdb_out);
154  }
155 }
156 
157 KDSTATUS
159  _In_ const VOID* Buffer,
160  _In_ size_t Length)
161 {
164  return finish_gdb_packet();
165 }
166 
167 KDSTATUS
170  _In_ BOOLEAN WithPrefix)
171 {
172  CHAR gdb_out[3];
173  CHAR* ptr = String->Buffer;
174  USHORT Length = String->Length;
175 
176  gdb_out[2] = '\0';
177 
179 
180  if (WithPrefix)
181  {
183  }
184 
185  /* Send the data */
186  while (Length--)
187  {
188  gdb_out[0] = hex_chars[(*ptr >> 4) & 0xf];
189  gdb_out[1] = hex_chars[*ptr++ & 0xf];
190  send_gdb_partial_packet(gdb_out);
191  }
192 
193  return finish_gdb_packet();
194 }
195 
196 KDSTATUS
198 {
199  char gdb_out[1024];
200  char* ptr = gdb_out;
202 
203  /* Report to GDB */
204  *ptr++ = 'T';
205 
207  {
209  ptr = exception_code_to_gdb(ExceptionRecord->ExceptionCode, ptr);
210  }
211  else
212  ptr += sprintf(ptr, "05");
213 
215  ptr += sprintf(ptr, "library:");
216 
217 #if MONOPROCESS
218  ptr += sprintf(ptr, "thread:%" PRIxPTR ";",
220 #else
221  ptr += sprintf(ptr, "thread:p%" PRIxPTR ".%" PRIxPTR ";",
224 #endif
225 
226  ptr += sprintf(ptr, "core:%x;", CurrentStateChange.Processor);
227  return send_gdb_packet(gdb_out);
228 }
229 
230 void
233 {
234  /* Just build a EXX packet and send it */
235  char gdb_out[4];
236  gdb_out[0] = 'E';
237  exception_code_to_gdb(Status, &gdb_out[1]);
238  gdb_out[3] = '\0';
239  send_gdb_packet(gdb_out);
240 }
void send_gdb_partial_packet(_In_ const CHAR *Buffer)
Definition: gdb_send.c:60
#define KdPacketReceived
Definition: kddll.h:5
const char hex_chars[]
Definition: gdb_send.c:11
#define TRUE
Definition: types.h:120
#define STATUS_ILLEGAL_INSTRUCTION
Definition: ntstatus.h:252
void send_gdb_ntstatus(_In_ NTSTATUS Status)
Definition: gdb_send.c:231
unsigned char Byte
Definition: zconf.h:391
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define handle_to_gdb_pid
Definition: kdgdb.h:45
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:173
static char * exception_code_to_gdb(NTSTATUS code, char *out)
Definition: gdb_send.c:17
NTSTATUS ExceptionCode
Definition: rtltypes.h:186
KDP_STATUS NTAPI KdpReceiveByte(OUT PUCHAR OutByte)
Definition: kdcom.c:310
static CHAR currentChecksum
Definition: gdb_send.c:12
static WCHAR String[]
Definition: stringtable.c:55
#define KD_DEBUGGER_NOT_PRESENT
Definition: kdfuncs.h:133
#define DbgKdExceptionStateChange
Definition: windbgkd.h:59
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:63
KDSTATUS gdb_send_exception()
Definition: gdb_send.c:197
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define KdPacketNeedsResend
Definition: kddll.h:7
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:371
void send_gdb_partial_memory(_In_ const VOID *Buffer, _In_ size_t Length)
Definition: gdb_send.c:140
#define STATUS_INTEGER_DIVIDE_BY_ZERO
Definition: ntstatus.h:370
static PVOID ptr
Definition: dispmode.c:27
unsigned char BOOLEAN
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
Definition: bufpool.h:45
KDSTATUS gdb_send_debug_io(_In_ PSTRING String, _In_ BOOLEAN WithPrefix)
Definition: gdb_send.c:168
void start_gdb_packet(void)
Definition: gdb_send.c:52
ULONG send_gdb_partial_binary(_In_ const VOID *Buffer, _In_ size_t Length)
Definition: gdb_send.c:108
#define DbgKdLoadSymbolsStateChange
Definition: windbgkd.h:60
HANDLE NTAPI PsGetThreadProcessId(IN PETHREAD Thread)
Definition: thread.c:745
static FILE * out
Definition: regtests2xml.c:44
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID NTAPI KdpSendByte(IN UCHAR Byte)
Definition: kdcom.c:280
EXCEPTION_RECORD64 ExceptionRecord
Definition: windbgkd.h:303
unsigned char UCHAR
Definition: xmlstorage.h:181
#define PRIxPTR
Definition: inttypes.h:236
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
unsigned short USHORT
Definition: pedump.c:61
ULONG KDSTATUS
Definition: kddll.h:4
UINT Sent
Definition: arping.c:39
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:475
DBGKM_EXCEPTION64 Exception
Definition: windbgkd.h:488
union _DBGKD_ANY_WAIT_STATE_CHANGE::@3421 u
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:171
FORCEINLINE UINT_PTR handle_to_gdb_tid(HANDLE Handle)
Definition: kdgdb.h:41
unsigned int ULONG
Definition: retypes.h:1
struct _ETHREAD * PETHREAD
Definition: nt_native.h:29
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define STATUS_ARRAY_BOUNDS_EXCEEDED
Definition: ntstatus.h:362
KDSTATUS finish_gdb_packet(void)
Definition: gdb_send.c:74