1e93f7393Sniklas /* Main code for remote server for GDB.
2*b725ae77Skettenis Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004
3*b725ae77Skettenis Free Software Foundation, Inc.
4e93f7393Sniklas
5e93f7393Sniklas This file is part of GDB.
6e93f7393Sniklas
7e93f7393Sniklas This program is free software; you can redistribute it and/or modify
8e93f7393Sniklas it under the terms of the GNU General Public License as published by
9e93f7393Sniklas the Free Software Foundation; either version 2 of the License, or
10e93f7393Sniklas (at your option) any later version.
11e93f7393Sniklas
12e93f7393Sniklas This program is distributed in the hope that it will be useful,
13e93f7393Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
14e93f7393Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15e93f7393Sniklas GNU General Public License for more details.
16e93f7393Sniklas
17e93f7393Sniklas You should have received a copy of the GNU General Public License
18e93f7393Sniklas along with this program; if not, write to the Free Software
19*b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
20*b725ae77Skettenis Boston, MA 02111-1307, USA. */
21e93f7393Sniklas
22e93f7393Sniklas #include "server.h"
23e93f7393Sniklas
24*b725ae77Skettenis #include <unistd.h>
25*b725ae77Skettenis #include <signal.h>
26*b725ae77Skettenis #include <sys/wait.h>
27*b725ae77Skettenis
28e93f7393Sniklas int cont_thread;
29e93f7393Sniklas int general_thread;
30*b725ae77Skettenis int step_thread;
31e93f7393Sniklas int thread_from_wait;
32e93f7393Sniklas int old_thread_from_wait;
33e93f7393Sniklas int extended_protocol;
34*b725ae77Skettenis int server_waiting;
35*b725ae77Skettenis
36*b725ae77Skettenis jmp_buf toplevel;
37*b725ae77Skettenis
38*b725ae77Skettenis /* The PID of the originally created or attached inferior. Used to
39*b725ae77Skettenis send signals to the process when GDB sends us an asynchronous interrupt
40*b725ae77Skettenis (user hitting Control-C in the client), and to wait for the child to exit
41*b725ae77Skettenis when no longer debugging it. */
42*b725ae77Skettenis
43*b725ae77Skettenis int signal_pid;
44*b725ae77Skettenis
45*b725ae77Skettenis static unsigned char
start_inferior(char * argv[],char * statusptr)46*b725ae77Skettenis start_inferior (char *argv[], char *statusptr)
47*b725ae77Skettenis {
48*b725ae77Skettenis signal (SIGTTOU, SIG_DFL);
49*b725ae77Skettenis signal (SIGTTIN, SIG_DFL);
50*b725ae77Skettenis
51*b725ae77Skettenis signal_pid = create_inferior (argv[0], argv);
52*b725ae77Skettenis
53*b725ae77Skettenis fprintf (stderr, "Process %s created; pid = %d\n", argv[0],
54*b725ae77Skettenis signal_pid);
55*b725ae77Skettenis
56*b725ae77Skettenis signal (SIGTTOU, SIG_IGN);
57*b725ae77Skettenis signal (SIGTTIN, SIG_IGN);
58*b725ae77Skettenis tcsetpgrp (fileno (stderr), signal_pid);
59*b725ae77Skettenis
60*b725ae77Skettenis /* Wait till we are at 1st instruction in program, return signal number. */
61*b725ae77Skettenis return mywait (statusptr, 0);
62*b725ae77Skettenis }
63*b725ae77Skettenis
64*b725ae77Skettenis static int
attach_inferior(int pid,char * statusptr,unsigned char * sigptr)65*b725ae77Skettenis attach_inferior (int pid, char *statusptr, unsigned char *sigptr)
66*b725ae77Skettenis {
67*b725ae77Skettenis /* myattach should return -1 if attaching is unsupported,
68*b725ae77Skettenis 0 if it succeeded, and call error() otherwise. */
69*b725ae77Skettenis
70*b725ae77Skettenis if (myattach (pid) != 0)
71*b725ae77Skettenis return -1;
72*b725ae77Skettenis
73*b725ae77Skettenis fprintf (stderr, "Attached; pid = %d\n", pid);
74*b725ae77Skettenis
75*b725ae77Skettenis /* FIXME - It may be that we should get the SIGNAL_PID from the
76*b725ae77Skettenis attach function, so that it can be the main thread instead of
77*b725ae77Skettenis whichever we were told to attach to. */
78*b725ae77Skettenis signal_pid = pid;
79*b725ae77Skettenis
80*b725ae77Skettenis *sigptr = mywait (statusptr, 0);
81*b725ae77Skettenis
82*b725ae77Skettenis return 0;
83*b725ae77Skettenis }
84*b725ae77Skettenis
85*b725ae77Skettenis extern int remote_debug;
86*b725ae77Skettenis
87*b725ae77Skettenis /* Handle all of the extended 'q' packets. */
88*b725ae77Skettenis void
handle_query(char * own_buf)89*b725ae77Skettenis handle_query (char *own_buf)
90*b725ae77Skettenis {
91*b725ae77Skettenis static struct inferior_list_entry *thread_ptr;
92*b725ae77Skettenis
93*b725ae77Skettenis if (strcmp ("qSymbol::", own_buf) == 0)
94*b725ae77Skettenis {
95*b725ae77Skettenis if (the_target->look_up_symbols != NULL)
96*b725ae77Skettenis (*the_target->look_up_symbols) ();
97*b725ae77Skettenis
98*b725ae77Skettenis strcpy (own_buf, "OK");
99*b725ae77Skettenis return;
100*b725ae77Skettenis }
101*b725ae77Skettenis
102*b725ae77Skettenis if (strcmp ("qfThreadInfo", own_buf) == 0)
103*b725ae77Skettenis {
104*b725ae77Skettenis thread_ptr = all_threads.head;
105*b725ae77Skettenis sprintf (own_buf, "m%x", thread_ptr->id);
106*b725ae77Skettenis thread_ptr = thread_ptr->next;
107*b725ae77Skettenis return;
108*b725ae77Skettenis }
109*b725ae77Skettenis
110*b725ae77Skettenis if (strcmp ("qsThreadInfo", own_buf) == 0)
111*b725ae77Skettenis {
112*b725ae77Skettenis if (thread_ptr != NULL)
113*b725ae77Skettenis {
114*b725ae77Skettenis sprintf (own_buf, "m%x", thread_ptr->id);
115*b725ae77Skettenis thread_ptr = thread_ptr->next;
116*b725ae77Skettenis return;
117*b725ae77Skettenis }
118*b725ae77Skettenis else
119*b725ae77Skettenis {
120*b725ae77Skettenis sprintf (own_buf, "l");
121*b725ae77Skettenis return;
122*b725ae77Skettenis }
123*b725ae77Skettenis }
124*b725ae77Skettenis
125*b725ae77Skettenis if (the_target->read_auxv != NULL
126*b725ae77Skettenis && strncmp ("qPart:auxv:read::", own_buf, 17) == 0)
127*b725ae77Skettenis {
128*b725ae77Skettenis char data[(PBUFSIZ - 1) / 2];
129*b725ae77Skettenis CORE_ADDR ofs;
130*b725ae77Skettenis unsigned int len;
131*b725ae77Skettenis int n;
132*b725ae77Skettenis decode_m_packet (&own_buf[17], &ofs, &len); /* "OFS,LEN" */
133*b725ae77Skettenis if (len > sizeof data)
134*b725ae77Skettenis len = sizeof data;
135*b725ae77Skettenis n = (*the_target->read_auxv) (ofs, data, len);
136*b725ae77Skettenis if (n == 0)
137*b725ae77Skettenis write_ok (own_buf);
138*b725ae77Skettenis else if (n < 0)
139*b725ae77Skettenis write_enn (own_buf);
140*b725ae77Skettenis else
141*b725ae77Skettenis convert_int_to_ascii (data, own_buf, n);
142*b725ae77Skettenis return;
143*b725ae77Skettenis }
144*b725ae77Skettenis
145*b725ae77Skettenis /* Otherwise we didn't know what packet it was. Say we didn't
146*b725ae77Skettenis understand it. */
147*b725ae77Skettenis own_buf[0] = 0;
148*b725ae77Skettenis }
149*b725ae77Skettenis
150*b725ae77Skettenis /* Parse vCont packets. */
151*b725ae77Skettenis void
handle_v_cont(char * own_buf,char * status,unsigned char * signal)152*b725ae77Skettenis handle_v_cont (char *own_buf, char *status, unsigned char *signal)
153*b725ae77Skettenis {
154*b725ae77Skettenis char *p, *q;
155*b725ae77Skettenis int n = 0, i = 0;
156*b725ae77Skettenis struct thread_resume *resume_info, default_action;
157*b725ae77Skettenis
158*b725ae77Skettenis /* Count the number of semicolons in the packet. There should be one
159*b725ae77Skettenis for every action. */
160*b725ae77Skettenis p = &own_buf[5];
161*b725ae77Skettenis while (p)
162*b725ae77Skettenis {
163*b725ae77Skettenis n++;
164*b725ae77Skettenis p++;
165*b725ae77Skettenis p = strchr (p, ';');
166*b725ae77Skettenis }
167*b725ae77Skettenis /* Allocate room for one extra action, for the default remain-stopped
168*b725ae77Skettenis behavior; if no default action is in the list, we'll need the extra
169*b725ae77Skettenis slot. */
170*b725ae77Skettenis resume_info = malloc ((n + 1) * sizeof (resume_info[0]));
171*b725ae77Skettenis
172*b725ae77Skettenis default_action.thread = -1;
173*b725ae77Skettenis default_action.leave_stopped = 1;
174*b725ae77Skettenis default_action.step = 0;
175*b725ae77Skettenis default_action.sig = 0;
176*b725ae77Skettenis
177*b725ae77Skettenis p = &own_buf[5];
178*b725ae77Skettenis i = 0;
179*b725ae77Skettenis while (*p)
180*b725ae77Skettenis {
181*b725ae77Skettenis p++;
182*b725ae77Skettenis
183*b725ae77Skettenis resume_info[i].leave_stopped = 0;
184*b725ae77Skettenis
185*b725ae77Skettenis if (p[0] == 's' || p[0] == 'S')
186*b725ae77Skettenis resume_info[i].step = 1;
187*b725ae77Skettenis else if (p[0] == 'c' || p[0] == 'C')
188*b725ae77Skettenis resume_info[i].step = 0;
189*b725ae77Skettenis else
190*b725ae77Skettenis goto err;
191*b725ae77Skettenis
192*b725ae77Skettenis if (p[0] == 'S' || p[0] == 'C')
193*b725ae77Skettenis {
194*b725ae77Skettenis int sig;
195*b725ae77Skettenis sig = strtol (p + 1, &q, 16);
196*b725ae77Skettenis if (p == q)
197*b725ae77Skettenis goto err;
198*b725ae77Skettenis p = q;
199*b725ae77Skettenis
200*b725ae77Skettenis if (!target_signal_to_host_p (sig))
201*b725ae77Skettenis goto err;
202*b725ae77Skettenis resume_info[i].sig = target_signal_to_host (sig);
203*b725ae77Skettenis }
204*b725ae77Skettenis else
205*b725ae77Skettenis {
206*b725ae77Skettenis resume_info[i].sig = 0;
207*b725ae77Skettenis p = p + 1;
208*b725ae77Skettenis }
209*b725ae77Skettenis
210*b725ae77Skettenis if (p[0] == 0)
211*b725ae77Skettenis {
212*b725ae77Skettenis resume_info[i].thread = -1;
213*b725ae77Skettenis default_action = resume_info[i];
214*b725ae77Skettenis
215*b725ae77Skettenis /* Note: we don't increment i here, we'll overwrite this entry
216*b725ae77Skettenis the next time through. */
217*b725ae77Skettenis }
218*b725ae77Skettenis else if (p[0] == ':')
219*b725ae77Skettenis {
220*b725ae77Skettenis resume_info[i].thread = strtol (p + 1, &q, 16);
221*b725ae77Skettenis if (p == q)
222*b725ae77Skettenis goto err;
223*b725ae77Skettenis p = q;
224*b725ae77Skettenis if (p[0] != ';' && p[0] != 0)
225*b725ae77Skettenis goto err;
226*b725ae77Skettenis
227*b725ae77Skettenis i++;
228*b725ae77Skettenis }
229*b725ae77Skettenis }
230*b725ae77Skettenis
231*b725ae77Skettenis resume_info[i] = default_action;
232*b725ae77Skettenis
233*b725ae77Skettenis /* Still used in occasional places in the backend. */
234*b725ae77Skettenis if (n == 1 && resume_info[0].thread != -1)
235*b725ae77Skettenis cont_thread = resume_info[0].thread;
236*b725ae77Skettenis else
237*b725ae77Skettenis cont_thread = -1;
238*b725ae77Skettenis set_desired_inferior (0);
239*b725ae77Skettenis
240*b725ae77Skettenis (*the_target->resume) (resume_info);
241*b725ae77Skettenis
242*b725ae77Skettenis free (resume_info);
243*b725ae77Skettenis
244*b725ae77Skettenis *signal = mywait (status, 1);
245*b725ae77Skettenis prepare_resume_reply (own_buf, *status, *signal);
246*b725ae77Skettenis return;
247*b725ae77Skettenis
248*b725ae77Skettenis err:
249*b725ae77Skettenis /* No other way to report an error... */
250*b725ae77Skettenis strcpy (own_buf, "");
251*b725ae77Skettenis free (resume_info);
252*b725ae77Skettenis return;
253*b725ae77Skettenis }
254*b725ae77Skettenis
255*b725ae77Skettenis /* Handle all of the extended 'v' packets. */
256*b725ae77Skettenis void
handle_v_requests(char * own_buf,char * status,unsigned char * signal)257*b725ae77Skettenis handle_v_requests (char *own_buf, char *status, unsigned char *signal)
258*b725ae77Skettenis {
259*b725ae77Skettenis if (strncmp (own_buf, "vCont;", 6) == 0)
260*b725ae77Skettenis {
261*b725ae77Skettenis handle_v_cont (own_buf, status, signal);
262*b725ae77Skettenis return;
263*b725ae77Skettenis }
264*b725ae77Skettenis
265*b725ae77Skettenis if (strncmp (own_buf, "vCont?", 6) == 0)
266*b725ae77Skettenis {
267*b725ae77Skettenis strcpy (own_buf, "vCont;c;C;s;S");
268*b725ae77Skettenis return;
269*b725ae77Skettenis }
270*b725ae77Skettenis
271*b725ae77Skettenis /* Otherwise we didn't know what packet it was. Say we didn't
272*b725ae77Skettenis understand it. */
273*b725ae77Skettenis own_buf[0] = 0;
274*b725ae77Skettenis return;
275*b725ae77Skettenis }
276*b725ae77Skettenis
277*b725ae77Skettenis void
myresume(int step,int sig)278*b725ae77Skettenis myresume (int step, int sig)
279*b725ae77Skettenis {
280*b725ae77Skettenis struct thread_resume resume_info[2];
281*b725ae77Skettenis int n = 0;
282*b725ae77Skettenis
283*b725ae77Skettenis if (step || sig || cont_thread > 0)
284*b725ae77Skettenis {
285*b725ae77Skettenis resume_info[0].thread
286*b725ae77Skettenis = ((struct inferior_list_entry *) current_inferior)->id;
287*b725ae77Skettenis resume_info[0].step = step;
288*b725ae77Skettenis resume_info[0].sig = sig;
289*b725ae77Skettenis resume_info[0].leave_stopped = 0;
290*b725ae77Skettenis n++;
291*b725ae77Skettenis }
292*b725ae77Skettenis resume_info[n].thread = -1;
293*b725ae77Skettenis resume_info[n].step = 0;
294*b725ae77Skettenis resume_info[n].sig = 0;
295*b725ae77Skettenis resume_info[n].leave_stopped = (cont_thread > 0);
296*b725ae77Skettenis
297*b725ae77Skettenis (*the_target->resume) (resume_info);
298*b725ae77Skettenis }
299*b725ae77Skettenis
300*b725ae77Skettenis static int attached;
301*b725ae77Skettenis
302*b725ae77Skettenis static void
gdbserver_usage(void)303*b725ae77Skettenis gdbserver_usage (void)
304*b725ae77Skettenis {
305*b725ae77Skettenis error ("Usage:\tgdbserver COMM PROG [ARGS ...]\n"
306*b725ae77Skettenis "\tgdbserver COMM --attach PID\n"
307*b725ae77Skettenis "\n"
308*b725ae77Skettenis "COMM may either be a tty device (for serial debugging), or \n"
309*b725ae77Skettenis "HOST:PORT to listen for a TCP connection.\n");
310*b725ae77Skettenis }
311e93f7393Sniklas
312e93f7393Sniklas int
main(int argc,char * argv[])313*b725ae77Skettenis main (int argc, char *argv[])
314e93f7393Sniklas {
315*b725ae77Skettenis char ch, status, *own_buf, mem_buf[2000];
316e93f7393Sniklas int i = 0;
317e93f7393Sniklas unsigned char signal;
318*b725ae77Skettenis unsigned int len;
319*b725ae77Skettenis CORE_ADDR mem_addr;
320*b725ae77Skettenis int bad_attach;
321*b725ae77Skettenis int pid;
322*b725ae77Skettenis char *arg_end;
323e93f7393Sniklas
324e93f7393Sniklas if (setjmp (toplevel))
325e93f7393Sniklas {
326e93f7393Sniklas fprintf (stderr, "Exiting\n");
327e93f7393Sniklas exit (1);
328e93f7393Sniklas }
329e93f7393Sniklas
330*b725ae77Skettenis bad_attach = 0;
331*b725ae77Skettenis pid = 0;
332*b725ae77Skettenis attached = 0;
333*b725ae77Skettenis if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
334*b725ae77Skettenis {
335*b725ae77Skettenis if (argc == 4
336*b725ae77Skettenis && argv[3] != '\0'
337*b725ae77Skettenis && (pid = strtoul (argv[3], &arg_end, 10)) != 0
338*b725ae77Skettenis && *arg_end == '\0')
339*b725ae77Skettenis {
340*b725ae77Skettenis ;
341*b725ae77Skettenis }
342*b725ae77Skettenis else
343*b725ae77Skettenis bad_attach = 1;
344*b725ae77Skettenis }
345e93f7393Sniklas
346*b725ae77Skettenis if (argc < 3 || bad_attach)
347*b725ae77Skettenis gdbserver_usage();
348e93f7393Sniklas
349*b725ae77Skettenis initialize_low ();
350*b725ae77Skettenis
351*b725ae77Skettenis own_buf = malloc (PBUFSIZ);
352*b725ae77Skettenis
353*b725ae77Skettenis if (pid == 0)
354*b725ae77Skettenis {
355*b725ae77Skettenis /* Wait till we are at first instruction in program. */
356*b725ae77Skettenis signal = start_inferior (&argv[2], &status);
357e93f7393Sniklas
358e93f7393Sniklas /* We are now stopped at the first instruction of the target process */
359*b725ae77Skettenis }
360*b725ae77Skettenis else
361*b725ae77Skettenis {
362*b725ae77Skettenis switch (attach_inferior (pid, &status, &signal))
363*b725ae77Skettenis {
364*b725ae77Skettenis case -1:
365*b725ae77Skettenis error ("Attaching not supported on this target");
366*b725ae77Skettenis break;
367*b725ae77Skettenis default:
368*b725ae77Skettenis attached = 1;
369*b725ae77Skettenis break;
370*b725ae77Skettenis }
371*b725ae77Skettenis }
372e93f7393Sniklas
373e93f7393Sniklas while (1)
374e93f7393Sniklas {
375e93f7393Sniklas remote_open (argv[1]);
376e93f7393Sniklas
377e93f7393Sniklas restart:
378e93f7393Sniklas setjmp (toplevel);
379e93f7393Sniklas while (getpkt (own_buf) > 0)
380e93f7393Sniklas {
381e93f7393Sniklas unsigned char sig;
382e93f7393Sniklas i = 0;
383e93f7393Sniklas ch = own_buf[i++];
384e93f7393Sniklas switch (ch)
385e93f7393Sniklas {
386*b725ae77Skettenis case 'q':
387*b725ae77Skettenis handle_query (own_buf);
388*b725ae77Skettenis break;
389*b725ae77Skettenis case 'd':
390*b725ae77Skettenis remote_debug = !remote_debug;
391*b725ae77Skettenis break;
392*b725ae77Skettenis case 'D':
393*b725ae77Skettenis fprintf (stderr, "Detaching from inferior\n");
394*b725ae77Skettenis detach_inferior ();
395*b725ae77Skettenis write_ok (own_buf);
396*b725ae77Skettenis putpkt (own_buf);
397*b725ae77Skettenis remote_close ();
398*b725ae77Skettenis
399*b725ae77Skettenis /* If we are attached, then we can exit. Otherwise, we need to
400*b725ae77Skettenis hang around doing nothing, until the child is gone. */
401*b725ae77Skettenis if (!attached)
402*b725ae77Skettenis {
403*b725ae77Skettenis int status, ret;
404*b725ae77Skettenis
405*b725ae77Skettenis do {
406*b725ae77Skettenis ret = waitpid (signal_pid, &status, 0);
407*b725ae77Skettenis if (WIFEXITED (status) || WIFSIGNALED (status))
408*b725ae77Skettenis break;
409*b725ae77Skettenis } while (ret != -1 || errno != ECHILD);
410*b725ae77Skettenis }
411*b725ae77Skettenis
412*b725ae77Skettenis exit (0);
413*b725ae77Skettenis
414e93f7393Sniklas case '!':
415*b725ae77Skettenis if (attached == 0)
416*b725ae77Skettenis {
417e93f7393Sniklas extended_protocol = 1;
418e93f7393Sniklas prepare_resume_reply (own_buf, status, signal);
419*b725ae77Skettenis }
420*b725ae77Skettenis else
421*b725ae77Skettenis {
422*b725ae77Skettenis /* We can not use the extended protocol if we are
423*b725ae77Skettenis attached, because we can not restart the running
424*b725ae77Skettenis program. So return unrecognized. */
425*b725ae77Skettenis own_buf[0] = '\0';
426*b725ae77Skettenis }
427e93f7393Sniklas break;
428e93f7393Sniklas case '?':
429e93f7393Sniklas prepare_resume_reply (own_buf, status, signal);
430e93f7393Sniklas break;
431e93f7393Sniklas case 'H':
432e93f7393Sniklas switch (own_buf[1])
433e93f7393Sniklas {
434e93f7393Sniklas case 'g':
435e93f7393Sniklas general_thread = strtol (&own_buf[2], NULL, 16);
436e93f7393Sniklas write_ok (own_buf);
437*b725ae77Skettenis set_desired_inferior (1);
438e93f7393Sniklas break;
439e93f7393Sniklas case 'c':
440e93f7393Sniklas cont_thread = strtol (&own_buf[2], NULL, 16);
441e93f7393Sniklas write_ok (own_buf);
442e93f7393Sniklas break;
443*b725ae77Skettenis case 's':
444*b725ae77Skettenis step_thread = strtol (&own_buf[2], NULL, 16);
445*b725ae77Skettenis write_ok (own_buf);
446*b725ae77Skettenis break;
447e93f7393Sniklas default:
448e93f7393Sniklas /* Silently ignore it so that gdb can extend the protocol
449e93f7393Sniklas without compatibility headaches. */
450e93f7393Sniklas own_buf[0] = '\0';
451e93f7393Sniklas break;
452e93f7393Sniklas }
453e93f7393Sniklas break;
454e93f7393Sniklas case 'g':
455*b725ae77Skettenis set_desired_inferior (1);
456*b725ae77Skettenis registers_to_string (own_buf);
457e93f7393Sniklas break;
458e93f7393Sniklas case 'G':
459*b725ae77Skettenis set_desired_inferior (1);
460*b725ae77Skettenis registers_from_string (&own_buf[1]);
461e93f7393Sniklas write_ok (own_buf);
462e93f7393Sniklas break;
463e93f7393Sniklas case 'm':
464e93f7393Sniklas decode_m_packet (&own_buf[1], &mem_addr, &len);
465*b725ae77Skettenis if (read_inferior_memory (mem_addr, mem_buf, len) == 0)
466e93f7393Sniklas convert_int_to_ascii (mem_buf, own_buf, len);
467*b725ae77Skettenis else
468*b725ae77Skettenis write_enn (own_buf);
469e93f7393Sniklas break;
470e93f7393Sniklas case 'M':
471e93f7393Sniklas decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
472e93f7393Sniklas if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
473e93f7393Sniklas write_ok (own_buf);
474e93f7393Sniklas else
475e93f7393Sniklas write_enn (own_buf);
476e93f7393Sniklas break;
477e93f7393Sniklas case 'C':
478e93f7393Sniklas convert_ascii_to_int (own_buf + 1, &sig, 1);
479*b725ae77Skettenis if (target_signal_to_host_p (sig))
480*b725ae77Skettenis signal = target_signal_to_host (sig);
481*b725ae77Skettenis else
482*b725ae77Skettenis signal = 0;
483*b725ae77Skettenis set_desired_inferior (0);
484*b725ae77Skettenis myresume (0, signal);
485*b725ae77Skettenis signal = mywait (&status, 1);
486e93f7393Sniklas prepare_resume_reply (own_buf, status, signal);
487e93f7393Sniklas break;
488e93f7393Sniklas case 'S':
489e93f7393Sniklas convert_ascii_to_int (own_buf + 1, &sig, 1);
490*b725ae77Skettenis if (target_signal_to_host_p (sig))
491*b725ae77Skettenis signal = target_signal_to_host (sig);
492*b725ae77Skettenis else
493*b725ae77Skettenis signal = 0;
494*b725ae77Skettenis set_desired_inferior (0);
495*b725ae77Skettenis myresume (1, signal);
496*b725ae77Skettenis signal = mywait (&status, 1);
497e93f7393Sniklas prepare_resume_reply (own_buf, status, signal);
498e93f7393Sniklas break;
499e93f7393Sniklas case 'c':
500*b725ae77Skettenis set_desired_inferior (0);
501e93f7393Sniklas myresume (0, 0);
502*b725ae77Skettenis signal = mywait (&status, 1);
503e93f7393Sniklas prepare_resume_reply (own_buf, status, signal);
504e93f7393Sniklas break;
505e93f7393Sniklas case 's':
506*b725ae77Skettenis set_desired_inferior (0);
507e93f7393Sniklas myresume (1, 0);
508*b725ae77Skettenis signal = mywait (&status, 1);
509e93f7393Sniklas prepare_resume_reply (own_buf, status, signal);
510e93f7393Sniklas break;
511e93f7393Sniklas case 'k':
512e93f7393Sniklas fprintf (stderr, "Killing inferior\n");
513e93f7393Sniklas kill_inferior ();
514e93f7393Sniklas /* When using the extended protocol, we start up a new
515e93f7393Sniklas debugging session. The traditional protocol will
516e93f7393Sniklas exit instead. */
517e93f7393Sniklas if (extended_protocol)
518e93f7393Sniklas {
519e93f7393Sniklas write_ok (own_buf);
520e93f7393Sniklas fprintf (stderr, "GDBserver restarting\n");
521e93f7393Sniklas
522e93f7393Sniklas /* Wait till we are at 1st instruction in prog. */
523*b725ae77Skettenis signal = start_inferior (&argv[2], &status);
524e93f7393Sniklas goto restart;
525e93f7393Sniklas break;
526e93f7393Sniklas }
527e93f7393Sniklas else
528e93f7393Sniklas {
529e93f7393Sniklas exit (0);
530e93f7393Sniklas break;
531e93f7393Sniklas }
532e93f7393Sniklas case 'T':
533e93f7393Sniklas if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
534e93f7393Sniklas write_ok (own_buf);
535e93f7393Sniklas else
536e93f7393Sniklas write_enn (own_buf);
537e93f7393Sniklas break;
538e93f7393Sniklas case 'R':
539e93f7393Sniklas /* Restarting the inferior is only supported in the
540e93f7393Sniklas extended protocol. */
541e93f7393Sniklas if (extended_protocol)
542e93f7393Sniklas {
543e93f7393Sniklas kill_inferior ();
544e93f7393Sniklas write_ok (own_buf);
545e93f7393Sniklas fprintf (stderr, "GDBserver restarting\n");
546e93f7393Sniklas
547e93f7393Sniklas /* Wait till we are at 1st instruction in prog. */
548*b725ae77Skettenis signal = start_inferior (&argv[2], &status);
549e93f7393Sniklas goto restart;
550e93f7393Sniklas break;
551e93f7393Sniklas }
552e93f7393Sniklas else
553e93f7393Sniklas {
554e93f7393Sniklas /* It is a request we don't understand. Respond with an
555e93f7393Sniklas empty packet so that gdb knows that we don't support this
556e93f7393Sniklas request. */
557e93f7393Sniklas own_buf[0] = '\0';
558e93f7393Sniklas break;
559e93f7393Sniklas }
560*b725ae77Skettenis case 'v':
561*b725ae77Skettenis /* Extended (long) request. */
562*b725ae77Skettenis handle_v_requests (own_buf, &status, &signal);
563*b725ae77Skettenis break;
564e93f7393Sniklas default:
565e93f7393Sniklas /* It is a request we don't understand. Respond with an
566e93f7393Sniklas empty packet so that gdb knows that we don't support this
567e93f7393Sniklas request. */
568e93f7393Sniklas own_buf[0] = '\0';
569e93f7393Sniklas break;
570e93f7393Sniklas }
571e93f7393Sniklas
572e93f7393Sniklas putpkt (own_buf);
573e93f7393Sniklas
574e93f7393Sniklas if (status == 'W')
575e93f7393Sniklas fprintf (stderr,
576*b725ae77Skettenis "\nChild exited with status %d\n", signal);
577e93f7393Sniklas if (status == 'X')
578*b725ae77Skettenis fprintf (stderr, "\nChild terminated with signal = 0x%x\n",
579*b725ae77Skettenis signal);
580e93f7393Sniklas if (status == 'W' || status == 'X')
581e93f7393Sniklas {
582e93f7393Sniklas if (extended_protocol)
583e93f7393Sniklas {
584e93f7393Sniklas fprintf (stderr, "Killing inferior\n");
585e93f7393Sniklas kill_inferior ();
586e93f7393Sniklas write_ok (own_buf);
587e93f7393Sniklas fprintf (stderr, "GDBserver restarting\n");
588e93f7393Sniklas
589e93f7393Sniklas /* Wait till we are at 1st instruction in prog. */
590*b725ae77Skettenis signal = start_inferior (&argv[2], &status);
591e93f7393Sniklas goto restart;
592e93f7393Sniklas break;
593e93f7393Sniklas }
594e93f7393Sniklas else
595e93f7393Sniklas {
596e93f7393Sniklas fprintf (stderr, "GDBserver exiting\n");
597e93f7393Sniklas exit (0);
598e93f7393Sniklas }
599e93f7393Sniklas }
600e93f7393Sniklas }
601e93f7393Sniklas
602e93f7393Sniklas /* We come here when getpkt fails.
603e93f7393Sniklas
604e93f7393Sniklas For the extended remote protocol we exit (and this is the only
605e93f7393Sniklas way we gracefully exit!).
606e93f7393Sniklas
607e93f7393Sniklas For the traditional remote protocol close the connection,
608e93f7393Sniklas and re-open it at the top of the loop. */
609e93f7393Sniklas if (extended_protocol)
610e93f7393Sniklas {
611e93f7393Sniklas remote_close ();
612e93f7393Sniklas exit (0);
613e93f7393Sniklas }
614e93f7393Sniklas else
615e93f7393Sniklas {
616*b725ae77Skettenis fprintf (stderr, "Remote side has terminated connection. "
617*b725ae77Skettenis "GDBserver will reopen the connection.\n");
618e93f7393Sniklas remote_close ();
619e93f7393Sniklas }
620e93f7393Sniklas }
621e93f7393Sniklas }
622