reactos/drivers/base/kdgdb/gdb_receive.c
2020-03-30 07:53:34 +00:00

113 lines
2.6 KiB
C

/*
* COPYRIGHT: GPL, see COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/base/kddll/gdb_receive.c
* PURPOSE: Base functions for the kernel debugger.
*/
#include "kdgdb.h"
/* GLOBALS ********************************************************************/
CHAR gdb_input[0x1000];
/* GLOBAL FUNCTIONS ***********************************************************/
char
hex_value(char ch)
{
if ((ch >= '0') && (ch <= '9'))
return (ch - '0');
if ((ch >= 'a') && (ch <= 'f'))
return (ch - 'a' + 10);
if ((ch >= 'A') && (ch <= 'F'))
return (ch - 'A' + 10);
return -1;
}
KDSTATUS
NTAPI
gdb_receive_packet(_Inout_ PKD_CONTEXT KdContext)
{
UCHAR* ByteBuffer;
UCHAR Byte;
KDSTATUS Status;
CHAR CheckSum, ReceivedCheckSum;
do
{
Status = KdpReceiveByte(&Byte);
if (Status != KdPacketReceived)
return Status;
} while (Byte != '$');
get_packet:
CheckSum = 0;
ByteBuffer = (UCHAR*)gdb_input;
while (TRUE)
{
/* Try to get a byte from the port */
Status = KdpReceiveByte(&Byte);
if (Status != KdPacketReceived)
return Status;
if (Byte == '#')
{
*ByteBuffer = '\0';
break;
}
CheckSum += (CHAR)Byte;
/* See if we should escape */
if (Byte == 0x7d)
{
Status = KdpReceiveByte(&Byte);
if (Status != KdPacketReceived)
return Status;
CheckSum += (CHAR)Byte;
Byte ^= 0x20;
}
*ByteBuffer++ = Byte;
}
/* Get Check sum (two bytes) */
Status = KdpReceiveByte(&Byte);
if (Status != KdPacketReceived)
goto end;
ReceivedCheckSum = hex_value(Byte) << 4;
Status = KdpReceiveByte(&Byte);
if (Status != KdPacketReceived)
goto end;
ReceivedCheckSum += hex_value(Byte);
end:
if (ReceivedCheckSum != CheckSum)
{
/* Do not acknowledge to GDB */
KDDBGPRINT("Check sums don't match!");
KdpSendByte('-');
return KdPacketNeedsResend;
}
/* Ensure there is nothing left in the pipe */
while (KdpPollByte(&Byte) == KdPacketReceived)
{
switch (Byte)
{
case '$':
KDDBGPRINT("Received new packet just after %s.\n", gdb_input);
goto get_packet;
case 0x03:
KdContext->KdpControlCPending = TRUE;
break;
}
}
/* Acknowledge */
KdpSendByte('+');
return KdPacketReceived;
}