#include "server.h"
int cont_thread;
int general_thread;
int thread_from_wait;
int old_thread_from_wait;
int extended_protocol;
jmp_buf toplevel;
int inferior_pid;
static unsigned char
start_inferior (char *argv[], char *statusptr)
{
inferior_pid = create_inferior (argv[0], argv);
fprintf (stderr, "Process %s created; pid = %d\n", argv[0], inferior_pid);
return mywait (statusptr);
}
extern int remote_debug;
int
main (int argc, char *argv[])
{
char ch, status, own_buf[PBUFSIZ], mem_buf[2000];
int i = 0;
unsigned char signal;
unsigned int len;
CORE_ADDR mem_addr;
if (setjmp (toplevel))
{
fprintf (stderr, "Exiting\n");
exit (1);
}
if (argc < 3)
error ("Usage: gdbserver tty prog [args ...]");
initialize_low ();
signal = start_inferior (&argv[2], &status);
while (1)
{
remote_open (argv[1]);
restart:
setjmp (toplevel);
while (getpkt (own_buf) > 0)
{
unsigned char sig;
i = 0;
ch = own_buf[i++];
switch (ch)
{
case 'd':
remote_debug = !remote_debug;
break;
case '!':
extended_protocol = 1;
prepare_resume_reply (own_buf, status, signal);
break;
case '?':
prepare_resume_reply (own_buf, status, signal);
break;
case 'H':
switch (own_buf[1])
{
case 'g':
general_thread = strtol (&own_buf[2], NULL, 16);
write_ok (own_buf);
fetch_inferior_registers (0);
break;
case 'c':
cont_thread = strtol (&own_buf[2], NULL, 16);
write_ok (own_buf);
break;
default:
own_buf[0] = '\0';
break;
}
break;
case 'g':
convert_int_to_ascii (registers, own_buf, REGISTER_BYTES);
break;
case 'G':
convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES);
store_inferior_registers (-1);
write_ok (own_buf);
break;
case 'm':
decode_m_packet (&own_buf[1], &mem_addr, &len);
read_inferior_memory (mem_addr, mem_buf, len);
convert_int_to_ascii (mem_buf, own_buf, len);
break;
case 'M':
decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
write_ok (own_buf);
else
write_enn (own_buf);
break;
case 'C':
convert_ascii_to_int (own_buf + 1, &sig, 1);
myresume (0, sig);
signal = mywait (&status);
prepare_resume_reply (own_buf, status, signal);
break;
case 'S':
convert_ascii_to_int (own_buf + 1, &sig, 1);
myresume (1, sig);
signal = mywait (&status);
prepare_resume_reply (own_buf, status, signal);
break;
case 'c':
myresume (0, 0);
signal = mywait (&status);
prepare_resume_reply (own_buf, status, signal);
break;
case 's':
myresume (1, 0);
signal = mywait (&status);
prepare_resume_reply (own_buf, status, signal);
break;
case 'k':
fprintf (stderr, "Killing inferior\n");
kill_inferior ();
if (extended_protocol)
{
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
else
{
exit (0);
break;
}
case 'T':
if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
write_ok (own_buf);
else
write_enn (own_buf);
break;
case 'R':
if (extended_protocol)
{
kill_inferior ();
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
else
{
own_buf[0] = '\0';
break;
}
default:
own_buf[0] = '\0';
break;
}
putpkt (own_buf);
if (status == 'W')
fprintf (stderr,
"\nChild exited with status %d\n", sig);
if (status == 'X')
fprintf (stderr, "\nChild terminated with signal = 0x%x\n", sig);
if (status == 'W' || status == 'X')
{
if (extended_protocol)
{
fprintf (stderr, "Killing inferior\n");
kill_inferior ();
write_ok (own_buf);
fprintf (stderr, "GDBserver restarting\n");
signal = start_inferior (&argv[2], &status);
goto restart;
break;
}
else
{
fprintf (stderr, "GDBserver exiting\n");
exit (0);
}
}
}
if (extended_protocol)
{
remote_close ();
exit (0);
}
else
{
fprintf (stderr, "Remote side has terminated connection. GDBserver will reopen the connection.\n");
remote_close ();
}
}
}