119370Spst/* Main code for remote server for GDB.
2130803Smarcel   Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004
398944Sobrien   Free Software Foundation, Inc.
419370Spst
598944Sobrien   This file is part of GDB.
619370Spst
798944Sobrien   This program is free software; you can redistribute it and/or modify
898944Sobrien   it under the terms of the GNU General Public License as published by
998944Sobrien   the Free Software Foundation; either version 2 of the License, or
1098944Sobrien   (at your option) any later version.
1119370Spst
1298944Sobrien   This program is distributed in the hope that it will be useful,
1398944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1498944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1598944Sobrien   GNU General Public License for more details.
1619370Spst
1798944Sobrien   You should have received a copy of the GNU General Public License
1898944Sobrien   along with this program; if not, write to the Free Software
1998944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2098944Sobrien   Boston, MA 02111-1307, USA.  */
2119370Spst
2219370Spst#include "server.h"
2319370Spst
24130803Smarcel#include <unistd.h>
25130803Smarcel#include <signal.h>
26130803Smarcel#include <sys/wait.h>
27130803Smarcel
2819370Spstint cont_thread;
2919370Spstint general_thread;
30130803Smarcelint step_thread;
3119370Spstint thread_from_wait;
3219370Spstint old_thread_from_wait;
3319370Spstint extended_protocol;
34130803Smarcelint server_waiting;
35130803Smarcel
3646283Sdfrjmp_buf toplevel;
3719370Spst
38130803Smarcel/* The PID of the originally created or attached inferior.  Used to
39130803Smarcel   send signals to the process when GDB sends us an asynchronous interrupt
40130803Smarcel   (user hitting Control-C in the client), and to wait for the child to exit
41130803Smarcel   when no longer debugging it.  */
42130803Smarcel
43130803Smarcelint signal_pid;
44130803Smarcel
4546283Sdfrstatic unsigned char
4698944Sobrienstart_inferior (char *argv[], char *statusptr)
4746283Sdfr{
48130803Smarcel  signal (SIGTTOU, SIG_DFL);
49130803Smarcel  signal (SIGTTIN, SIG_DFL);
5046283Sdfr
51130803Smarcel  signal_pid = create_inferior (argv[0], argv);
52130803Smarcel
53130803Smarcel  fprintf (stderr, "Process %s created; pid = %d\n", argv[0],
54130803Smarcel	   signal_pid);
55130803Smarcel
56130803Smarcel  signal (SIGTTOU, SIG_IGN);
57130803Smarcel  signal (SIGTTIN, SIG_IGN);
58130803Smarcel  tcsetpgrp (fileno (stderr), signal_pid);
59130803Smarcel
6046283Sdfr  /* Wait till we are at 1st instruction in program, return signal number.  */
61130803Smarcel  return mywait (statusptr, 0);
6246283Sdfr}
6346283Sdfr
6498944Sobrienstatic int
6598944Sobrienattach_inferior (int pid, char *statusptr, unsigned char *sigptr)
6698944Sobrien{
6798944Sobrien  /* myattach should return -1 if attaching is unsupported,
6898944Sobrien     0 if it succeeded, and call error() otherwise.  */
69130803Smarcel
7098944Sobrien  if (myattach (pid) != 0)
7198944Sobrien    return -1;
7298944Sobrien
73130803Smarcel  fprintf (stderr, "Attached; pid = %d\n", pid);
7498944Sobrien
75130803Smarcel  /* FIXME - It may be that we should get the SIGNAL_PID from the
76130803Smarcel     attach function, so that it can be the main thread instead of
77130803Smarcel     whichever we were told to attach to.  */
78130803Smarcel  signal_pid = pid;
7998944Sobrien
80130803Smarcel  *sigptr = mywait (statusptr, 0);
81130803Smarcel
8298944Sobrien  return 0;
8398944Sobrien}
8498944Sobrien
8546283Sdfrextern int remote_debug;
8646283Sdfr
87130803Smarcel/* Handle all of the extended 'q' packets.  */
88130803Smarcelvoid
89130803Smarcelhandle_query (char *own_buf)
90130803Smarcel{
91130803Smarcel  static struct inferior_list_entry *thread_ptr;
92130803Smarcel
93130803Smarcel  if (strcmp ("qSymbol::", own_buf) == 0)
94130803Smarcel    {
95130803Smarcel      if (the_target->look_up_symbols != NULL)
96130803Smarcel	(*the_target->look_up_symbols) ();
97130803Smarcel
98130803Smarcel      strcpy (own_buf, "OK");
99130803Smarcel      return;
100130803Smarcel    }
101130803Smarcel
102130803Smarcel  if (strcmp ("qfThreadInfo", own_buf) == 0)
103130803Smarcel    {
104130803Smarcel      thread_ptr = all_threads.head;
105130803Smarcel      sprintf (own_buf, "m%x", thread_ptr->id);
106130803Smarcel      thread_ptr = thread_ptr->next;
107130803Smarcel      return;
108130803Smarcel    }
109130803Smarcel
110130803Smarcel  if (strcmp ("qsThreadInfo", own_buf) == 0)
111130803Smarcel    {
112130803Smarcel      if (thread_ptr != NULL)
113130803Smarcel	{
114130803Smarcel	  sprintf (own_buf, "m%x", thread_ptr->id);
115130803Smarcel	  thread_ptr = thread_ptr->next;
116130803Smarcel	  return;
117130803Smarcel	}
118130803Smarcel      else
119130803Smarcel	{
120130803Smarcel	  sprintf (own_buf, "l");
121130803Smarcel	  return;
122130803Smarcel	}
123130803Smarcel    }
124130803Smarcel
125130803Smarcel  if (the_target->read_auxv != NULL
126130803Smarcel      && strncmp ("qPart:auxv:read::", own_buf, 17) == 0)
127130803Smarcel    {
128130803Smarcel      char data[(PBUFSIZ - 1) / 2];
129130803Smarcel      CORE_ADDR ofs;
130130803Smarcel      unsigned int len;
131130803Smarcel      int n;
132130803Smarcel      decode_m_packet (&own_buf[17], &ofs, &len); /* "OFS,LEN" */
133130803Smarcel      if (len > sizeof data)
134130803Smarcel	len = sizeof data;
135130803Smarcel      n = (*the_target->read_auxv) (ofs, data, len);
136130803Smarcel      if (n == 0)
137130803Smarcel	write_ok (own_buf);
138130803Smarcel      else if (n < 0)
139130803Smarcel	write_enn (own_buf);
140130803Smarcel      else
141130803Smarcel	convert_int_to_ascii (data, own_buf, n);
142130803Smarcel      return;
143130803Smarcel    }
144130803Smarcel
145130803Smarcel  /* Otherwise we didn't know what packet it was.  Say we didn't
146130803Smarcel     understand it.  */
147130803Smarcel  own_buf[0] = 0;
148130803Smarcel}
149130803Smarcel
150130803Smarcel/* Parse vCont packets.  */
151130803Smarcelvoid
152130803Smarcelhandle_v_cont (char *own_buf, char *status, unsigned char *signal)
153130803Smarcel{
154130803Smarcel  char *p, *q;
155130803Smarcel  int n = 0, i = 0;
156130803Smarcel  struct thread_resume *resume_info, default_action;
157130803Smarcel
158130803Smarcel  /* Count the number of semicolons in the packet.  There should be one
159130803Smarcel     for every action.  */
160130803Smarcel  p = &own_buf[5];
161130803Smarcel  while (p)
162130803Smarcel    {
163130803Smarcel      n++;
164130803Smarcel      p++;
165130803Smarcel      p = strchr (p, ';');
166130803Smarcel    }
167130803Smarcel  /* Allocate room for one extra action, for the default remain-stopped
168130803Smarcel     behavior; if no default action is in the list, we'll need the extra
169130803Smarcel     slot.  */
170130803Smarcel  resume_info = malloc ((n + 1) * sizeof (resume_info[0]));
171130803Smarcel
172130803Smarcel  default_action.thread = -1;
173130803Smarcel  default_action.leave_stopped = 1;
174130803Smarcel  default_action.step = 0;
175130803Smarcel  default_action.sig = 0;
176130803Smarcel
177130803Smarcel  p = &own_buf[5];
178130803Smarcel  i = 0;
179130803Smarcel  while (*p)
180130803Smarcel    {
181130803Smarcel      p++;
182130803Smarcel
183130803Smarcel      resume_info[i].leave_stopped = 0;
184130803Smarcel
185130803Smarcel      if (p[0] == 's' || p[0] == 'S')
186130803Smarcel	resume_info[i].step = 1;
187130803Smarcel      else if (p[0] == 'c' || p[0] == 'C')
188130803Smarcel	resume_info[i].step = 0;
189130803Smarcel      else
190130803Smarcel	goto err;
191130803Smarcel
192130803Smarcel      if (p[0] == 'S' || p[0] == 'C')
193130803Smarcel	{
194130803Smarcel	  int sig;
195130803Smarcel	  sig = strtol (p + 1, &q, 16);
196130803Smarcel	  if (p == q)
197130803Smarcel	    goto err;
198130803Smarcel	  p = q;
199130803Smarcel
200130803Smarcel	  if (!target_signal_to_host_p (sig))
201130803Smarcel	    goto err;
202130803Smarcel	  resume_info[i].sig = target_signal_to_host (sig);
203130803Smarcel	}
204130803Smarcel      else
205130803Smarcel	{
206130803Smarcel	  resume_info[i].sig = 0;
207130803Smarcel	  p = p + 1;
208130803Smarcel	}
209130803Smarcel
210130803Smarcel      if (p[0] == 0)
211130803Smarcel	{
212130803Smarcel	  resume_info[i].thread = -1;
213130803Smarcel	  default_action = resume_info[i];
214130803Smarcel
215130803Smarcel	  /* Note: we don't increment i here, we'll overwrite this entry
216130803Smarcel	     the next time through.  */
217130803Smarcel	}
218130803Smarcel      else if (p[0] == ':')
219130803Smarcel	{
220130803Smarcel	  resume_info[i].thread = strtol (p + 1, &q, 16);
221130803Smarcel	  if (p == q)
222130803Smarcel	    goto err;
223130803Smarcel	  p = q;
224130803Smarcel	  if (p[0] != ';' && p[0] != 0)
225130803Smarcel	    goto err;
226130803Smarcel
227130803Smarcel	  i++;
228130803Smarcel	}
229130803Smarcel    }
230130803Smarcel
231130803Smarcel  resume_info[i] = default_action;
232130803Smarcel
233130803Smarcel  /* Still used in occasional places in the backend.  */
234130803Smarcel  if (n == 1 && resume_info[0].thread != -1)
235130803Smarcel    cont_thread = resume_info[0].thread;
236130803Smarcel  else
237130803Smarcel    cont_thread = -1;
238130803Smarcel  set_desired_inferior (0);
239130803Smarcel
240130803Smarcel  (*the_target->resume) (resume_info);
241130803Smarcel
242130803Smarcel  free (resume_info);
243130803Smarcel
244130803Smarcel  *signal = mywait (status, 1);
245130803Smarcel  prepare_resume_reply (own_buf, *status, *signal);
246130803Smarcel  return;
247130803Smarcel
248130803Smarcelerr:
249130803Smarcel  /* No other way to report an error... */
250130803Smarcel  strcpy (own_buf, "");
251130803Smarcel  free (resume_info);
252130803Smarcel  return;
253130803Smarcel}
254130803Smarcel
255130803Smarcel/* Handle all of the extended 'v' packets.  */
256130803Smarcelvoid
257130803Smarcelhandle_v_requests (char *own_buf, char *status, unsigned char *signal)
258130803Smarcel{
259130803Smarcel  if (strncmp (own_buf, "vCont;", 6) == 0)
260130803Smarcel    {
261130803Smarcel      handle_v_cont (own_buf, status, signal);
262130803Smarcel      return;
263130803Smarcel    }
264130803Smarcel
265130803Smarcel  if (strncmp (own_buf, "vCont?", 6) == 0)
266130803Smarcel    {
267130803Smarcel      strcpy (own_buf, "vCont;c;C;s;S");
268130803Smarcel      return;
269130803Smarcel    }
270130803Smarcel
271130803Smarcel  /* Otherwise we didn't know what packet it was.  Say we didn't
272130803Smarcel     understand it.  */
273130803Smarcel  own_buf[0] = 0;
274130803Smarcel  return;
275130803Smarcel}
276130803Smarcel
277130803Smarcelvoid
278130803Smarcelmyresume (int step, int sig)
279130803Smarcel{
280130803Smarcel  struct thread_resume resume_info[2];
281130803Smarcel  int n = 0;
282130803Smarcel
283130803Smarcel  if (step || sig || cont_thread > 0)
284130803Smarcel    {
285130803Smarcel      resume_info[0].thread
286130803Smarcel	= ((struct inferior_list_entry *) current_inferior)->id;
287130803Smarcel      resume_info[0].step = step;
288130803Smarcel      resume_info[0].sig = sig;
289130803Smarcel      resume_info[0].leave_stopped = 0;
290130803Smarcel      n++;
291130803Smarcel    }
292130803Smarcel  resume_info[n].thread = -1;
293130803Smarcel  resume_info[n].step = 0;
294130803Smarcel  resume_info[n].sig = 0;
295130803Smarcel  resume_info[n].leave_stopped = (cont_thread > 0);
296130803Smarcel
297130803Smarcel  (*the_target->resume) (resume_info);
298130803Smarcel}
299130803Smarcel
300130803Smarcelstatic int attached;
301130803Smarcel
302130803Smarcelstatic void
303130803Smarcelgdbserver_usage (void)
304130803Smarcel{
305130803Smarcel  error ("Usage:\tgdbserver COMM PROG [ARGS ...]\n"
306130803Smarcel	 "\tgdbserver COMM --attach PID\n"
307130803Smarcel	 "\n"
308130803Smarcel	 "COMM may either be a tty device (for serial debugging), or \n"
309130803Smarcel	 "HOST:PORT to listen for a TCP connection.\n");
310130803Smarcel}
311130803Smarcel
31219370Spstint
31398944Sobrienmain (int argc, char *argv[])
31419370Spst{
31598944Sobrien  char ch, status, *own_buf, mem_buf[2000];
31619370Spst  int i = 0;
31719370Spst  unsigned char signal;
31846283Sdfr  unsigned int len;
31946283Sdfr  CORE_ADDR mem_addr;
320130803Smarcel  int bad_attach;
321130803Smarcel  int pid;
32298944Sobrien  char *arg_end;
32319370Spst
32498944Sobrien  if (setjmp (toplevel))
32519370Spst    {
32698944Sobrien      fprintf (stderr, "Exiting\n");
32798944Sobrien      exit (1);
32819370Spst    }
32919370Spst
330130803Smarcel  bad_attach = 0;
331130803Smarcel  pid = 0;
332130803Smarcel  attached = 0;
33398944Sobrien  if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
33498944Sobrien    {
33598944Sobrien      if (argc == 4
33698944Sobrien	  && argv[3] != '\0'
33798944Sobrien	  && (pid = strtoul (argv[3], &arg_end, 10)) != 0
33898944Sobrien	  && *arg_end == '\0')
33998944Sobrien	{
34098944Sobrien	  ;
34198944Sobrien	}
34298944Sobrien      else
34398944Sobrien	bad_attach = 1;
34498944Sobrien    }
34519370Spst
34698944Sobrien  if (argc < 3 || bad_attach)
347130803Smarcel    gdbserver_usage();
34819370Spst
34998944Sobrien  initialize_low ();
35019370Spst
35198944Sobrien  own_buf = malloc (PBUFSIZ);
35298944Sobrien
35398944Sobrien  if (pid == 0)
35498944Sobrien    {
35598944Sobrien      /* Wait till we are at first instruction in program.  */
35698944Sobrien      signal = start_inferior (&argv[2], &status);
35798944Sobrien
35898944Sobrien      /* We are now stopped at the first instruction of the target process */
35998944Sobrien    }
36098944Sobrien  else
36198944Sobrien    {
36298944Sobrien      switch (attach_inferior (pid, &status, &signal))
36398944Sobrien	{
36498944Sobrien	case -1:
36598944Sobrien	  error ("Attaching not supported on this target");
36698944Sobrien	  break;
36798944Sobrien	default:
36898944Sobrien	  attached = 1;
36998944Sobrien	  break;
37098944Sobrien	}
37198944Sobrien    }
37298944Sobrien
37319370Spst  while (1)
37419370Spst    {
37519370Spst      remote_open (argv[1]);
37619370Spst
37798944Sobrien    restart:
37898944Sobrien      setjmp (toplevel);
37919370Spst      while (getpkt (own_buf) > 0)
38019370Spst	{
38119370Spst	  unsigned char sig;
38219370Spst	  i = 0;
38319370Spst	  ch = own_buf[i++];
38419370Spst	  switch (ch)
38519370Spst	    {
386130803Smarcel	    case 'q':
387130803Smarcel	      handle_query (own_buf);
388130803Smarcel	      break;
38946283Sdfr	    case 'd':
39046283Sdfr	      remote_debug = !remote_debug;
39146283Sdfr	      break;
392130803Smarcel	    case 'D':
393130803Smarcel	      fprintf (stderr, "Detaching from inferior\n");
394130803Smarcel	      detach_inferior ();
395130803Smarcel	      write_ok (own_buf);
396130803Smarcel	      putpkt (own_buf);
397130803Smarcel	      remote_close ();
398130803Smarcel
399130803Smarcel	      /* If we are attached, then we can exit.  Otherwise, we need to
400130803Smarcel		 hang around doing nothing, until the child is gone.  */
401130803Smarcel	      if (!attached)
402130803Smarcel		{
403130803Smarcel		  int status, ret;
404130803Smarcel
405130803Smarcel		  do {
406130803Smarcel		    ret = waitpid (signal_pid, &status, 0);
407130803Smarcel		    if (WIFEXITED (status) || WIFSIGNALED (status))
408130803Smarcel		      break;
409130803Smarcel		  } while (ret != -1 || errno != ECHILD);
410130803Smarcel		}
411130803Smarcel
412130803Smarcel	      exit (0);
413130803Smarcel
41419370Spst	    case '!':
41598944Sobrien	      if (attached == 0)
41698944Sobrien		{
41798944Sobrien		  extended_protocol = 1;
41898944Sobrien		  prepare_resume_reply (own_buf, status, signal);
41998944Sobrien		}
42098944Sobrien	      else
42198944Sobrien		{
42298944Sobrien		  /* We can not use the extended protocol if we are
42398944Sobrien		     attached, because we can not restart the running
42498944Sobrien		     program.  So return unrecognized.  */
42598944Sobrien		  own_buf[0] = '\0';
42698944Sobrien		}
42719370Spst	      break;
42819370Spst	    case '?':
42919370Spst	      prepare_resume_reply (own_buf, status, signal);
43019370Spst	      break;
43119370Spst	    case 'H':
43219370Spst	      switch (own_buf[1])
43319370Spst		{
43419370Spst		case 'g':
43519370Spst		  general_thread = strtol (&own_buf[2], NULL, 16);
43619370Spst		  write_ok (own_buf);
437130803Smarcel		  set_desired_inferior (1);
43819370Spst		  break;
43919370Spst		case 'c':
44019370Spst		  cont_thread = strtol (&own_buf[2], NULL, 16);
44119370Spst		  write_ok (own_buf);
44219370Spst		  break;
443130803Smarcel		case 's':
444130803Smarcel		  step_thread = strtol (&own_buf[2], NULL, 16);
445130803Smarcel		  write_ok (own_buf);
446130803Smarcel		  break;
44719370Spst		default:
44819370Spst		  /* Silently ignore it so that gdb can extend the protocol
44919370Spst		     without compatibility headaches.  */
45019370Spst		  own_buf[0] = '\0';
45119370Spst		  break;
45219370Spst		}
45319370Spst	      break;
45419370Spst	    case 'g':
455130803Smarcel	      set_desired_inferior (1);
45698944Sobrien	      registers_to_string (own_buf);
45719370Spst	      break;
45819370Spst	    case 'G':
459130803Smarcel	      set_desired_inferior (1);
46098944Sobrien	      registers_from_string (&own_buf[1]);
46119370Spst	      write_ok (own_buf);
46219370Spst	      break;
46319370Spst	    case 'm':
46419370Spst	      decode_m_packet (&own_buf[1], &mem_addr, &len);
465130803Smarcel	      if (read_inferior_memory (mem_addr, mem_buf, len) == 0)
466130803Smarcel		convert_int_to_ascii (mem_buf, own_buf, len);
467130803Smarcel	      else
468130803Smarcel		write_enn (own_buf);
46919370Spst	      break;
47019370Spst	    case 'M':
47119370Spst	      decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
47219370Spst	      if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
47319370Spst		write_ok (own_buf);
47419370Spst	      else
47519370Spst		write_enn (own_buf);
47619370Spst	      break;
47719370Spst	    case 'C':
47819370Spst	      convert_ascii_to_int (own_buf + 1, &sig, 1);
47998944Sobrien	      if (target_signal_to_host_p (sig))
48098944Sobrien		signal = target_signal_to_host (sig);
48198944Sobrien	      else
48298944Sobrien		signal = 0;
483130803Smarcel	      set_desired_inferior (0);
48498944Sobrien	      myresume (0, signal);
485130803Smarcel	      signal = mywait (&status, 1);
48619370Spst	      prepare_resume_reply (own_buf, status, signal);
48719370Spst	      break;
48819370Spst	    case 'S':
48919370Spst	      convert_ascii_to_int (own_buf + 1, &sig, 1);
49098944Sobrien	      if (target_signal_to_host_p (sig))
49198944Sobrien		signal = target_signal_to_host (sig);
49298944Sobrien	      else
49398944Sobrien		signal = 0;
494130803Smarcel	      set_desired_inferior (0);
49598944Sobrien	      myresume (1, signal);
496130803Smarcel	      signal = mywait (&status, 1);
49719370Spst	      prepare_resume_reply (own_buf, status, signal);
49819370Spst	      break;
49919370Spst	    case 'c':
500130803Smarcel	      set_desired_inferior (0);
50119370Spst	      myresume (0, 0);
502130803Smarcel	      signal = mywait (&status, 1);
50319370Spst	      prepare_resume_reply (own_buf, status, signal);
50419370Spst	      break;
50519370Spst	    case 's':
506130803Smarcel	      set_desired_inferior (0);
50719370Spst	      myresume (1, 0);
508130803Smarcel	      signal = mywait (&status, 1);
50919370Spst	      prepare_resume_reply (own_buf, status, signal);
51019370Spst	      break;
51119370Spst	    case 'k':
51219370Spst	      fprintf (stderr, "Killing inferior\n");
51319370Spst	      kill_inferior ();
51419370Spst	      /* When using the extended protocol, we start up a new
51598944Sobrien	         debugging session.   The traditional protocol will
51619370Spst	         exit instead.  */
51719370Spst	      if (extended_protocol)
51819370Spst		{
51919370Spst		  write_ok (own_buf);
52019370Spst		  fprintf (stderr, "GDBserver restarting\n");
52119370Spst
52219370Spst		  /* Wait till we are at 1st instruction in prog.  */
52346283Sdfr		  signal = start_inferior (&argv[2], &status);
52419370Spst		  goto restart;
52519370Spst		  break;
52619370Spst		}
52719370Spst	      else
52819370Spst		{
52919370Spst		  exit (0);
53019370Spst		  break;
53119370Spst		}
53219370Spst	    case 'T':
53319370Spst	      if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
53419370Spst		write_ok (own_buf);
53519370Spst	      else
53619370Spst		write_enn (own_buf);
53719370Spst	      break;
53819370Spst	    case 'R':
53919370Spst	      /* Restarting the inferior is only supported in the
54098944Sobrien	         extended protocol.  */
54119370Spst	      if (extended_protocol)
54219370Spst		{
54319370Spst		  kill_inferior ();
54419370Spst		  write_ok (own_buf);
54519370Spst		  fprintf (stderr, "GDBserver restarting\n");
54619370Spst
54719370Spst		  /* Wait till we are at 1st instruction in prog.  */
54846283Sdfr		  signal = start_inferior (&argv[2], &status);
54919370Spst		  goto restart;
55019370Spst		  break;
55119370Spst		}
55219370Spst	      else
55319370Spst		{
55419370Spst		  /* It is a request we don't understand.  Respond with an
55519370Spst		     empty packet so that gdb knows that we don't support this
55619370Spst		     request.  */
55719370Spst		  own_buf[0] = '\0';
55819370Spst		  break;
55919370Spst		}
560130803Smarcel	    case 'v':
561130803Smarcel	      /* Extended (long) request.  */
562130803Smarcel	      handle_v_requests (own_buf, &status, &signal);
563130803Smarcel	      break;
56419370Spst	    default:
56519370Spst	      /* It is a request we don't understand.  Respond with an
56698944Sobrien	         empty packet so that gdb knows that we don't support this
56798944Sobrien	         request.  */
56819370Spst	      own_buf[0] = '\0';
56919370Spst	      break;
57019370Spst	    }
57119370Spst
57219370Spst	  putpkt (own_buf);
57319370Spst
57419370Spst	  if (status == 'W')
57519370Spst	    fprintf (stderr,
576130803Smarcel		     "\nChild exited with status %d\n", signal);
57719370Spst	  if (status == 'X')
578130803Smarcel	    fprintf (stderr, "\nChild terminated with signal = 0x%x\n",
579130803Smarcel		     signal);
58019370Spst	  if (status == 'W' || status == 'X')
58119370Spst	    {
58219370Spst	      if (extended_protocol)
58319370Spst		{
58419370Spst		  fprintf (stderr, "Killing inferior\n");
58519370Spst		  kill_inferior ();
58619370Spst		  write_ok (own_buf);
58719370Spst		  fprintf (stderr, "GDBserver restarting\n");
58819370Spst
58919370Spst		  /* Wait till we are at 1st instruction in prog.  */
59046283Sdfr		  signal = start_inferior (&argv[2], &status);
59119370Spst		  goto restart;
59219370Spst		  break;
59319370Spst		}
59419370Spst	      else
59519370Spst		{
59619370Spst		  fprintf (stderr, "GDBserver exiting\n");
59719370Spst		  exit (0);
59819370Spst		}
59919370Spst	    }
60019370Spst	}
60119370Spst
60219370Spst      /* We come here when getpkt fails.
60319370Spst
60498944Sobrien         For the extended remote protocol we exit (and this is the only
60598944Sobrien         way we gracefully exit!).
60619370Spst
60798944Sobrien         For the traditional remote protocol close the connection,
60898944Sobrien         and re-open it at the top of the loop.  */
60919370Spst      if (extended_protocol)
61019370Spst	{
61119370Spst	  remote_close ();
61219370Spst	  exit (0);
61319370Spst	}
61419370Spst      else
61519370Spst	{
61698944Sobrien	  fprintf (stderr, "Remote side has terminated connection.  "
61798944Sobrien			   "GDBserver will reopen the connection.\n");
61819370Spst	  remote_close ();
61919370Spst	}
62019370Spst    }
62119370Spst}
622