static void send_kd_debug_io( _In_ DBGKD_DEBUG_IO* DebugIO, _In_ PSTRING String) { if (InException) return; switch (DebugIO->ApiNumber) { case DbgKdPrintStringApi: gdb_send_debug_io(String); break; default: /* FIXME */ while (1); } }
static void send_kd_debug_io( _In_ DBGKD_DEBUG_IO* DebugIO, _In_ PSTRING String) { if (InException) return; switch (DebugIO->ApiNumber) { case DbgKdPrintStringApi: gdb_send_debug_io(String, TRUE); break; default: KDDBGPRINT("Unknown ApiNumber %u.\n", DebugIO->ApiNumber); while (1); } }
/* q* packets */ static void handle_gdb_query(void) { if (strncmp(gdb_input, "qSupported:", 11) == 0) { #if MONOPROCESS send_gdb_packet("PacketSize=1000;"); #else send_gdb_packet("PacketSize=1000;multiprocess+;"); #endif return; } if (strncmp(gdb_input, "qAttached", 9) == 0) { #if MONOPROCESS send_gdb_packet("1"); #else UINT_PTR queried_pid = hex_to_pid(&gdb_input[10]); /* Let's say we created system process */ if (gdb_pid_to_handle(queried_pid) == NULL) send_gdb_packet("0"); else send_gdb_packet("1"); #endif return; } if (strncmp(gdb_input, "qRcmd,", 6) == 0) { send_gdb_packet("OK"); return; } if (strcmp(gdb_input, "qC") == 0) { char gdb_out[64]; #if MONOPROCESS sprintf(gdb_out, "QC:%"PRIxPTR";", handle_to_gdb_tid(PsGetThreadId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread))); #else sprintf(gdb_out, "QC:p%"PRIxPTR".%"PRIxPTR";", handle_to_gdb_pid(PsGetThreadProcessId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread)), handle_to_gdb_tid(PsGetThreadId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread))); #endif send_gdb_packet(gdb_out); return; } if ((strncmp(gdb_input, "qfThreadInfo", 12) == 0) || (strncmp(gdb_input, "qsThreadInfo", 12) == 0)) { BOOLEAN FirstThread = TRUE; PEPROCESS Process; PETHREAD Thread; char gdb_out[1024]; char* ptr = gdb_out; BOOLEAN Resuming = strncmp(gdb_input, "qsThreadInfo", 12) == 0; /* Keep track of where we are. */ static LIST_ENTRY* CurrentProcessEntry; static LIST_ENTRY* CurrentThreadEntry; ptr = gdb_out; *ptr++ = 'm'; /* NULL terminate in case we got nothing more to iterate */ *ptr = '\0'; if (!Resuming) { /* Initialize the entries */ CurrentProcessEntry = ProcessListHead->Flink; CurrentThreadEntry = NULL; /* Start with idle thread */ #if MONOPROCESS ptr = gdb_out + sprintf(gdb_out, "m1"); #else ptr = gdb_out + sprintf(gdb_out, "mp1.1"); #endif FirstThread = FALSE; } if (CurrentProcessEntry == NULL) /* Ps is not initialized */ { send_gdb_packet(Resuming ? "l" : gdb_out); return; } /* List all the processes */ for ( ; CurrentProcessEntry != ProcessListHead; CurrentProcessEntry = CurrentProcessEntry->Flink) { Process = CONTAINING_RECORD(CurrentProcessEntry, EPROCESS, ActiveProcessLinks); if (CurrentThreadEntry != NULL) CurrentThreadEntry = CurrentThreadEntry->Flink; else CurrentThreadEntry = Process->ThreadListHead.Flink; /* List threads from this process */ for ( ; CurrentThreadEntry != &Process->ThreadListHead; CurrentThreadEntry = CurrentThreadEntry->Flink) { Thread = CONTAINING_RECORD(CurrentThreadEntry, ETHREAD, ThreadListEntry); /* See if we should add a comma */ if (FirstThread) { FirstThread = FALSE; } else { *ptr++ = ','; } #if MONOPROCESS ptr += _snprintf(ptr, 1024 - (ptr - gdb_out), "%p", handle_to_gdb_tid(Thread->Cid.UniqueThread)); #else ptr += _snprintf(ptr, 1024 - (ptr - gdb_out), "p%p.%p", handle_to_gdb_pid(Process->UniqueProcessId), handle_to_gdb_tid(Thread->Cid.UniqueThread)); #endif if (ptr > (gdb_out + 1024)) { /* send what we got */ send_gdb_packet(gdb_out); /* GDB can ask anything at this point, it isn't necessarily a qsThreadInfo packet */ return; } } /* We're done for this process */ CurrentThreadEntry = NULL; } if (gdb_out[1] == '\0') { /* We didn't iterate over anything, meaning we were already done */ send_gdb_packet("l"); } else { send_gdb_packet(gdb_out); } /* GDB can ask anything at this point, it isn't necessarily a qsThreadInfo packet */ return; } if (strncmp(gdb_input, "qThreadExtraInfo,", 17) == 0) { ULONG_PTR Pid, Tid; PETHREAD Thread; PEPROCESS Process; char out_string[64]; STRING String = {0, 64, out_string}; KDDBGPRINT("Giving extra info for"); #if MONOPROCESS Pid = 0; Tid = hex_to_tid(&gdb_input[17]); KDDBGPRINT(" %p.\n", Tid); Thread = find_thread(Pid, Tid); Process = CONTAINING_RECORD(Thread->Tcb.Process, EPROCESS, Pcb); #else Pid = hex_to_pid(&gdb_input[2]); Tid = hex_to_tid(strstr(gdb_input, ".") + 1); /* We cannot use PsLookupProcessThreadByCid as we could be running at any IRQL. * So loop. */ KDDBGPRINT(" p%p.%p.\n", Pid, Tid); Process = find_process(Pid); Thread = find_thread(Pid, Tid); #endif if (PsGetThreadProcessId(Thread) == 0) { String.Length = sprintf(out_string, "SYSTEM"); } else { String.Length = sprintf(out_string, "%.*s", 16, Process->ImageFileName); } gdb_send_debug_io(&String, FALSE); return; } if (strncmp(gdb_input, "qOffsets", 8) == 0) { /* We load ntoskrnl at 0x80800000 while compiling it at 0x00800000 base adress */ send_gdb_packet("TextSeg=80000000"); return; } if (strcmp(gdb_input, "qTStatus") == 0) { /* No tracepoint support */ send_gdb_packet("T0"); return; } KDDBGPRINT("KDGDB: Unknown query: %s\n", gdb_input); send_gdb_packet(""); return; }