ReactOS  0.4.15-dev-3299-gbe8e5fc
amd64_sup.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS KD dll - GDB stub
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Base functions for the kernel debugger
5  * COPYRIGHT: Copyright 2021 Jérôme Gardou
6  */
7 
8 #include "kdgdb.h"
9 
11 {
12  RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP,
13  R8, R9, R10, R11, R12, R13, R14, R15,
14  RIP,
16  CS, SS, DS, ES, FS, GS,
17  ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
19 };
20 
21 static const unsigned char reg_size[] =
22 {
23  8, 8, 8, 8, 8, 8, 8, 8,
24  8, 8, 8, 8, 8, 8, 8, 8,
25  8,
26  4,
27  4, 4, 4, 4, 4, 4,
28  10, 10, 10, 10, 10, 10, 10, 10,
29  8, 8, 8, 8, 8, 8, 8, 8
30 };
31 
32 static
33 void*
35 {
36  switch (name)
37  {
38  case RAX: return &ctx->Rax;
39  case RBX: return &ctx->Rbx;
40  case RCX: return &ctx->Rcx;
41  case RDX: return &ctx->Rdx;
42  case RSP: return &ctx->Rsp;
43  case RBP: return &ctx->Rbp;
44  case RSI: return &ctx->Rsi;
45  case RDI: return &ctx->Rdi;
46  case RIP: return &ctx->Rip;
47  case R8: return &ctx->R8;
48  case R9: return &ctx->R9;
49  case R10: return &ctx->R10;
50  case R11: return &ctx->R11;
51  case R12: return &ctx->R12;
52  case R13: return &ctx->R13;
53  case R14: return &ctx->R14;
54  case R15: return &ctx->R15;
55  case EFLAGS: return &ctx->EFlags;
56  case CS: return &ctx->SegCs;
57  case DS: return &ctx->SegSs;
58  case ES: return &ctx->SegEs;
59  case FS: return &ctx->SegFs;
60  case GS: return &ctx->SegGs;
61  case SS: return &ctx->SegSs;
62  }
63 #undef return_reg
64  return 0;
65 }
66 
67 static
68 void*
70 {
71  static const void* NullValue = NULL;
72 
73 #if 0
74  if (Thread->Tcb.TrapFrame)
75  {
76  PKTRAP_FRAME TrapFrame = Thread->Tcb.TrapFrame;
77 
78  switch (reg_name)
79  {
80  case RAX: return &TrapFrame->Rax;
81  case RBX: return &TrapFrame->Rbx;
82  case RCX: return &TrapFrame->Rcx;
83  case RDX: return &TrapFrame->Rdx;
84  case RSP: return &TrapFrame->Rsp;
85  case RBP: return &TrapFrame->Rbp;
86  case RSI: return &TrapFrame->Rsi;
87  case RDI: return &TrapFrame->Rdi;
88  case RIP: return &TrapFrame->Rip;
89  case R8: return &TrapFrame->R8;
90  case R9: return &TrapFrame->R9;
91  case R10: return &TrapFrame->R10;
92  case R11: return &TrapFrame->R11;
93  case EFLAGS: return &TrapFrame->EFlags;
94  case CS: return &TrapFrame->SegCs;
95  case DS: return &TrapFrame->SegSs;
96  case ES: return &TrapFrame->SegEs;
97  case FS: return &TrapFrame->SegFs;
98  case GS: return &TrapFrame->SegGs;
99  case SS: return &TrapFrame->SegSs;
100  default:
101  KDDBGPRINT("Unhandled regname: %d.\n", reg_name);
102  }
103  }
104  else
105 #endif
106  if (!Thread->Tcb.InitialStack)
107  {
108  /* Terminated thread ? */
109  switch (reg_name)
110  {
111  case RSP:
112  case RBP:
113  case RIP:
114  KDDBGPRINT("Returning NULL for register %d.\n", reg_name);
115  return &NullValue;
116  default:
117  return NULL;
118  }
119  }
120  else
121  {
122  switch(reg_name)
123  {
124  case RSP: return &Thread->Tcb.KernelStack;
125  case RIP:
126  {
128  return &Rsp[3];
129  }
130  case RBP:
131  {
133  return &Rsp[4];
134  }
135  default:
136  return NULL;
137  }
138  }
139 
140  return NULL;
141 }
142 
143 KDSTATUS
145 {
146  CHAR RegisterStr[17];
147  UCHAR* RegisterPtr;
148  unsigned short i;
149  unsigned short size;
150 
152 
153  KDDBGPRINT("Sending registers of thread %" PRIxPTR ".\n", gdb_dbg_tid);
154  KDDBGPRINT("Current thread_id: %p.\n", PsGetThreadId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread));
155  if (((gdb_dbg_pid == 0) && (gdb_dbg_tid == 0)) ||
157  {
158  for (i = 0; i < 24; i++)
159  {
160  RegisterPtr = ctx_to_reg(&CurrentContext, i);
161  size = reg_size[i] * 2;
162  RegisterStr[size] = 0;
163  while (size)
164  {
165  size--;
166  RegisterStr[size] = hex_chars[RegisterPtr[size/2] & 0xF];
167  size--;
168  RegisterStr[size] = hex_chars[RegisterPtr[size/2] >> 4];
169  }
170 
171  send_gdb_partial_packet(RegisterStr);
172  }
173  }
174  else
175  {
176  PETHREAD DbgThread;
177 
178  DbgThread = find_thread(gdb_dbg_pid, gdb_dbg_tid);
179 
180  if (DbgThread == NULL)
181  {
182  /* Thread is dead */
184  return finish_gdb_packet();
185  }
186 
187  for (i = 0; i < 24; i++)
188  {
189  RegisterPtr = thread_to_reg(DbgThread, i);
190  size = reg_size[i] * 2;
191  RegisterStr[size] = 0;
192 
193  while (size)
194  {
195  if (RegisterPtr)
196  {
197  size--;
198  RegisterStr[size] = hex_chars[RegisterPtr[size/2] & 0xF];
199  size--;
200  RegisterStr[size] = hex_chars[RegisterPtr[size/2] >> 4];
201  }
202  else
203  {
204  size--;
205  RegisterStr[size] = 'x';
206  size--;
207  RegisterStr[size] = 'x';
208  }
209  }
210 
211  send_gdb_partial_packet(RegisterStr);
212  }
213  }
214 
215  return finish_gdb_packet();
216 }
217 
218 KDSTATUS
220 {
221  enum reg_name reg_name;
222  void *ptr;
223 
224  /* Get the GDB register name (gdb_input = "pXX") */
225  reg_name = (hex_value(gdb_input[1]) << 4) | hex_value(gdb_input[2]);
226 
227  if (((gdb_dbg_pid == 0) && (gdb_dbg_tid == 0)) ||
229  {
230  /* We can get it from the context of the current exception */
232  }
233  else
234  {
235  PETHREAD DbgThread;
236 
237  DbgThread = find_thread(gdb_dbg_pid, gdb_dbg_tid);
238 
239  if (DbgThread == NULL)
240  {
241  /* Thread is dead */
242  return send_gdb_packet("E03");
243  }
244 
245  ptr = thread_to_reg(DbgThread, reg_name);
246  }
247 
248  if (!ptr)
249  {
250  unsigned char size = reg_size[reg_name];
252  while (size--)
254  return finish_gdb_packet();
255  }
256  else
257  {
258  KDDBGPRINT("KDDBG : Sending registers as memory.\n");
260  }
261 }
262 
263 
UINT64 R8
Definition: ketypes.h:325
void send_gdb_partial_packet(_In_ const CHAR *Buffer)
Definition: gdb_send.c:60
UINT64 Rbp
Definition: ketypes.h:376
UINT64 R10
Definition: ketypes.h:327
Definition: amd64_sup.c:17
Definition: amd64_sup.c:12
const char hex_chars[]
Definition: gdb_send.c:11
Definition: amd64_sup.c:18
FORCEINLINE HANDLE gdb_tid_to_handle(UINT_PTR Tid)
Definition: kdgdb.h:35
Definition: amd64_sup.c:13
UINT64 Rbx
Definition: ketypes.h:373
UINT64 R9
Definition: ketypes.h:326
CONTEXT CurrentContext
Definition: kdpacket.c:29
#define KDDBGPRINT(...)
Definition: kddll.h:19
Definition: amd64_sup.c:17
char CHAR
Definition: xmlstorage.h:175
Definition: amd64_sup.c:13
Definition: amd64_sup.c:14
KTHREAD Tcb
Definition: pstypes.h:1103
USHORT SegFs
Definition: ketypes.h:370
Definition: amd64_sup.c:17
PKTRAP_FRAME TrapFrame
Definition: ketypes.h:1706
Definition: amd64_sup.c:17
static void * ctx_to_reg(CONTEXT *ctx, enum reg_name name)
Definition: amd64_sup.c:34
Definition: amd64_sup.c:12
static void * thread_to_reg(PETHREAD Thread, enum reg_name reg_name)
Definition: amd64_sup.c:69
Definition: amd64_sup.c:17
Definition: amd64_sup.c:13
Definition: amd64_sup.c:13
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
Definition: amd64_sup.c:12
uint32_t ULONG_PTR
Definition: typedefs.h:65
UINT64 Rsi
Definition: ketypes.h:375
USHORT SegGs
Definition: ketypes.h:371
UINT64 Rax
Definition: ketypes.h:322
USHORT SegEs
Definition: ketypes.h:369
static PVOID ptr
Definition: dispmode.c:27
USHORT SegCs
Definition: ketypes.h:384
PETHREAD find_thread(_In_ UINT_PTR Pid, _In_ UINT_PTR Tid)
Definition: utils.c:41
PVOID KernelStack
Definition: ketypes.h:1607
Definition: amd64_sup.c:13
KDSTATUS gdb_send_registers(void)
Definition: amd64_sup.c:144
Definition: amd64_sup.c:16
Definition: amd64_sup.c:16
char hex_value(char ch)
Definition: gdb_receive.c:15
UINT_PTR gdb_dbg_tid
Definition: gdb_input.c:21
void start_gdb_packet(void)
Definition: gdb_send.c:52
Definition: amd64_sup.c:17
UINT_PTR gdb_dbg_pid
Definition: gdb_input.c:20
GLsizeiptr size
Definition: glext.h:5919
Definition: amd64_sup.c:12
Definition: amd64_sup.c:17
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
static const unsigned char reg_size[]
Definition: amd64_sup.c:21
unsigned char UCHAR
Definition: xmlstorage.h:181
UINT64 Rdx
Definition: ketypes.h:324
Definition: amd64_sup.c:17
#define PRIxPTR
Definition: inttypes.h:236
Definition: amd64_sup.c:12
Definition: amd64_sup.c:12
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
UINT64 R11
Definition: ketypes.h:328
USHORT SegSs
Definition: ketypes.h:391
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
ULONG KDSTATUS
Definition: kddll.h:4
UINT64 Rsp
Definition: ketypes.h:390
Definition: amd64_sup.c:12
#define NULL
Definition: types.h:112
Definition: amd64_sup.c:13
UINT64 Rdi
Definition: ketypes.h:374
Definition: name.c:38
UINT64 Rip
Definition: ketypes.h:383
reg_name
Definition: amd64_sup.c:10
Definition: amd64_sup.c:16
uint32_t * PULONG_PTR
Definition: typedefs.h:65
Definition: amd64_sup.c:13
Definition: amd64_sup.c:18
CHAR gdb_input[0x1000]
Definition: gdb_receive.c:11
Definition: amd64_sup.c:16
Definition: amd64_sup.c:12
UINT64 Rcx
Definition: ketypes.h:323
PVOID InitialStack
Definition: ketypes.h:1596
Definition: amd64_sup.c:16
ULONG EFlags
Definition: ketypes.h:388
KDSTATUS finish_gdb_packet(void)
Definition: gdb_send.c:74
Definition: amd64_sup.c:13
KDSTATUS gdb_send_register(void)
Definition: amd64_sup.c:219
Definition: amd64_sup.c:16