]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbserver/server.c
Copyright updates for 2007.
[thirdparty/binutils-gdb.git] / gdb / gdbserver / server.c
CommitLineData
c906108c 1/* Main code for remote server for GDB.
6aba47ca
DJ
2 Copyright (C) 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003,
3 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
6f0f660e
EZ
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
c906108c
SS
21
22#include "server.h"
23
a9fa9f7d
DJ
24#include <unistd.h>
25#include <signal.h>
b80864fb 26#if HAVE_SYS_WAIT_H
a9fa9f7d 27#include <sys/wait.h>
b80864fb 28#endif
a9fa9f7d 29
a1928bad
DJ
30unsigned long cont_thread;
31unsigned long general_thread;
32unsigned long step_thread;
33unsigned long thread_from_wait;
34unsigned long old_thread_from_wait;
c906108c 35int extended_protocol;
0d62e5e8
DJ
36int server_waiting;
37
89be2091
DJ
38int pass_signals[TARGET_SIGNAL_LAST];
39
c906108c 40jmp_buf toplevel;
c906108c 41
a9fa9f7d
DJ
42/* The PID of the originally created or attached inferior. Used to
43 send signals to the process when GDB sends us an asynchronous interrupt
44 (user hitting Control-C in the client), and to wait for the child to exit
45 when no longer debugging it. */
46
a1928bad 47unsigned long signal_pid;
a9fa9f7d 48
290fadea
RS
49#ifdef SIGTTOU
50/* A file descriptor for the controlling terminal. */
51int terminal_fd;
52
53/* TERMINAL_FD's original foreground group. */
54pid_t old_foreground_pgrp;
55
56/* Hand back terminal ownership to the original foreground group. */
57
58static void
59restore_old_foreground_pgrp (void)
60{
61 tcsetpgrp (terminal_fd, old_foreground_pgrp);
62}
63#endif
64
fc620387 65static int
da85418c 66start_inferior (char *argv[], char *statusptr)
c906108c 67{
b80864fb 68#ifdef SIGTTOU
a9fa9f7d
DJ
69 signal (SIGTTOU, SIG_DFL);
70 signal (SIGTTIN, SIG_DFL);
b80864fb 71#endif
a9fa9f7d
DJ
72
73 signal_pid = create_inferior (argv[0], argv);
0d62e5e8 74
a1928bad 75 fprintf (stderr, "Process %s created; pid = %ld\n", argv[0],
a9fa9f7d 76 signal_pid);
b80864fb 77 fflush (stderr);
a9fa9f7d 78
b80864fb 79#ifdef SIGTTOU
a9fa9f7d
DJ
80 signal (SIGTTOU, SIG_IGN);
81 signal (SIGTTIN, SIG_IGN);
290fadea
RS
82 terminal_fd = fileno (stderr);
83 old_foreground_pgrp = tcgetpgrp (terminal_fd);
84 tcsetpgrp (terminal_fd, signal_pid);
85 atexit (restore_old_foreground_pgrp);
b80864fb 86#endif
c906108c
SS
87
88 /* Wait till we are at 1st instruction in program, return signal number. */
0d62e5e8 89 return mywait (statusptr, 0);
c906108c
SS
90}
91
45b7b345 92static int
fc620387 93attach_inferior (int pid, char *statusptr, int *sigptr)
45b7b345
DJ
94{
95 /* myattach should return -1 if attaching is unsupported,
96 0 if it succeeded, and call error() otherwise. */
a9fa9f7d 97
45b7b345
DJ
98 if (myattach (pid) != 0)
99 return -1;
100
6910d122 101 fprintf (stderr, "Attached; pid = %d\n", pid);
b80864fb 102 fflush (stderr);
6910d122 103
a9fa9f7d
DJ
104 /* FIXME - It may be that we should get the SIGNAL_PID from the
105 attach function, so that it can be the main thread instead of
106 whichever we were told to attach to. */
107 signal_pid = pid;
108
0d62e5e8 109 *sigptr = mywait (statusptr, 0);
45b7b345 110
9db87ebd
DJ
111 /* GDB knows to ignore the first SIGSTOP after attaching to a running
112 process using the "attach" command, but this is different; it's
113 just using "target remote". Pretend it's just starting up. */
b80864fb
DJ
114 if (*statusptr == 'T' && *sigptr == TARGET_SIGNAL_STOP)
115 *sigptr = TARGET_SIGNAL_TRAP;
9db87ebd 116
45b7b345
DJ
117 return 0;
118}
119
c906108c 120extern int remote_debug;
ce3a066d 121
0876f84a
DJ
122/* Decode a qXfer read request. Return 0 if everything looks OK,
123 or -1 otherwise. */
124
125static int
126decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len)
127{
128 /* Extract and NUL-terminate the annex. */
129 *annex = buf;
130 while (*buf && *buf != ':')
131 buf++;
132 if (*buf == '\0')
133 return -1;
134 *buf++ = 0;
135
136 /* After the read/write marker and annex, qXfer looks like a
137 traditional 'm' packet. */
138 decode_m_packet (buf, ofs, len);
139
140 return 0;
141}
142
143/* Write the response to a successful qXfer read. Returns the
144 length of the (binary) data stored in BUF, corresponding
145 to as much of DATA/LEN as we could fit. IS_MORE controls
146 the first character of the response. */
147static int
148write_qxfer_response (char *buf, unsigned char *data, int len, int is_more)
149{
150 int out_len;
151
152 if (is_more)
153 buf[0] = 'm';
154 else
155 buf[0] = 'l';
156
157 return remote_escape_output (data, len, (unsigned char *) buf + 1, &out_len,
158 PBUFSIZ - 2) + 1;
159}
160
89be2091
DJ
161/* Handle all of the extended 'Q' packets. */
162void
163handle_general_set (char *own_buf)
164{
165 if (strncmp ("QPassSignals:", own_buf, strlen ("QPassSignals:")) == 0)
166 {
167 int numsigs = (int) TARGET_SIGNAL_LAST, i;
168 const char *p = own_buf + strlen ("QPassSignals:");
169 CORE_ADDR cursig;
170
171 p = decode_address_to_semicolon (&cursig, p);
172 for (i = 0; i < numsigs; i++)
173 {
174 if (i == cursig)
175 {
176 pass_signals[i] = 1;
177 if (*p == '\0')
178 /* Keep looping, to clear the remaining signals. */
179 cursig = -1;
180 else
181 p = decode_address_to_semicolon (&cursig, p);
182 }
183 else
184 pass_signals[i] = 0;
185 }
186 strcpy (own_buf, "OK");
187 return;
188 }
189
190 /* Otherwise we didn't know what packet it was. Say we didn't
191 understand it. */
192 own_buf[0] = 0;
193}
194
ce3a066d
DJ
195/* Handle all of the extended 'q' packets. */
196void
0876f84a 197handle_query (char *own_buf, int *new_packet_len_p)
ce3a066d 198{
0d62e5e8
DJ
199 static struct inferior_list_entry *thread_ptr;
200
ce3a066d
DJ
201 if (strcmp ("qSymbol::", own_buf) == 0)
202 {
2f2893d9
DJ
203 if (the_target->look_up_symbols != NULL)
204 (*the_target->look_up_symbols) ();
205
ce3a066d
DJ
206 strcpy (own_buf, "OK");
207 return;
208 }
209
0d62e5e8
DJ
210 if (strcmp ("qfThreadInfo", own_buf) == 0)
211 {
212 thread_ptr = all_threads.head;
a06660f7 213 sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr));
0d62e5e8
DJ
214 thread_ptr = thread_ptr->next;
215 return;
216 }
aa691b87 217
0d62e5e8
DJ
218 if (strcmp ("qsThreadInfo", own_buf) == 0)
219 {
220 if (thread_ptr != NULL)
221 {
a06660f7 222 sprintf (own_buf, "m%x", thread_to_gdb_id ((struct thread_info *)thread_ptr));
0d62e5e8
DJ
223 thread_ptr = thread_ptr->next;
224 return;
225 }
226 else
227 {
228 sprintf (own_buf, "l");
229 return;
230 }
231 }
aa691b87 232
52fb6437
NS
233 if (the_target->read_offsets != NULL
234 && strcmp ("qOffsets", own_buf) == 0)
235 {
236 CORE_ADDR text, data;
237
238 if (the_target->read_offsets (&text, &data))
239 sprintf (own_buf, "Text=%lX;Data=%lX;Bss=%lX",
240 (long)text, (long)data, (long)data);
241 else
242 write_enn (own_buf);
243
244 return;
245 }
246
aa691b87 247 if (the_target->read_auxv != NULL
0876f84a 248 && strncmp ("qXfer:auxv:read:", own_buf, 16) == 0)
aa691b87 249 {
0876f84a
DJ
250 unsigned char *data;
251 int n;
aa691b87
RM
252 CORE_ADDR ofs;
253 unsigned int len;
0876f84a
DJ
254 char *annex;
255
256 /* Reject any annex; grab the offset and length. */
257 if (decode_xfer_read (own_buf + 16, &annex, &ofs, &len) < 0
258 || annex[0] != '\0')
259 {
260 strcpy (own_buf, "E00");
261 return;
262 }
263
264 /* Read one extra byte, as an indicator of whether there is
265 more. */
266 if (len > PBUFSIZ - 2)
267 len = PBUFSIZ - 2;
268 data = malloc (len + 1);
269 n = (*the_target->read_auxv) (ofs, data, len + 1);
000ef4f0
DJ
270 if (n < 0)
271 write_enn (own_buf);
272 else if (n > len)
0876f84a 273 *new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
aa691b87 274 else
0876f84a
DJ
275 *new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
276
277 free (data);
278
aa691b87
RM
279 return;
280 }
281
be2a5f71
DJ
282 /* Protocol features query. */
283 if (strncmp ("qSupported", own_buf, 10) == 0
284 && (own_buf[10] == ':' || own_buf[10] == '\0'))
285 {
89be2091 286 sprintf (own_buf, "PacketSize=%x;QPassSignals+", PBUFSIZ - 1);
0876f84a
DJ
287
288 if (the_target->read_auxv != NULL)
9f2e1e63 289 strcat (own_buf, ";qXfer:auxv:read+");
0876f84a 290
be2a5f71
DJ
291 return;
292 }
293
dae5f5cf
DJ
294 /* Thread-local storage support. */
295 if (the_target->get_tls_address != NULL
296 && strncmp ("qGetTLSAddr:", own_buf, 12) == 0)
297 {
298 char *p = own_buf + 12;
299 CORE_ADDR parts[3], address = 0;
300 int i, err;
301
302 for (i = 0; i < 3; i++)
303 {
304 char *p2;
305 int len;
306
307 if (p == NULL)
308 break;
309
310 p2 = strchr (p, ',');
311 if (p2)
312 {
313 len = p2 - p;
314 p2++;
315 }
316 else
317 {
318 len = strlen (p);
319 p2 = NULL;
320 }
321
322 decode_address (&parts[i], p, len);
323 p = p2;
324 }
325
326 if (p != NULL || i < 3)
327 err = 1;
328 else
329 {
330 struct thread_info *thread = gdb_id_to_thread (parts[0]);
331
332 if (thread == NULL)
333 err = 2;
334 else
335 err = the_target->get_tls_address (thread, parts[1], parts[2],
336 &address);
337 }
338
339 if (err == 0)
340 {
341 sprintf (own_buf, "%llx", address);
342 return;
343 }
344 else if (err > 0)
345 {
346 write_enn (own_buf);
347 return;
348 }
349
350 /* Otherwise, pretend we do not understand this packet. */
351 }
352
ce3a066d
DJ
353 /* Otherwise we didn't know what packet it was. Say we didn't
354 understand it. */
355 own_buf[0] = 0;
356}
357
64386c31
DJ
358/* Parse vCont packets. */
359void
fc620387 360handle_v_cont (char *own_buf, char *status, int *signal)
64386c31
DJ
361{
362 char *p, *q;
363 int n = 0, i = 0;
364 struct thread_resume *resume_info, default_action;
365
366 /* Count the number of semicolons in the packet. There should be one
367 for every action. */
368 p = &own_buf[5];
369 while (p)
370 {
371 n++;
372 p++;
373 p = strchr (p, ';');
374 }
375 /* Allocate room for one extra action, for the default remain-stopped
376 behavior; if no default action is in the list, we'll need the extra
377 slot. */
378 resume_info = malloc ((n + 1) * sizeof (resume_info[0]));
379
380 default_action.thread = -1;
381 default_action.leave_stopped = 1;
382 default_action.step = 0;
383 default_action.sig = 0;
384
385 p = &own_buf[5];
386 i = 0;
387 while (*p)
388 {
389 p++;
390
391 resume_info[i].leave_stopped = 0;
392
393 if (p[0] == 's' || p[0] == 'S')
394 resume_info[i].step = 1;
395 else if (p[0] == 'c' || p[0] == 'C')
396 resume_info[i].step = 0;
397 else
398 goto err;
399
400 if (p[0] == 'S' || p[0] == 'C')
401 {
402 int sig;
403 sig = strtol (p + 1, &q, 16);
404 if (p == q)
405 goto err;
406 p = q;
407
408 if (!target_signal_to_host_p (sig))
409 goto err;
410 resume_info[i].sig = target_signal_to_host (sig);
411 }
412 else
413 {
414 resume_info[i].sig = 0;
415 p = p + 1;
416 }
417
418 if (p[0] == 0)
419 {
420 resume_info[i].thread = -1;
421 default_action = resume_info[i];
422
423 /* Note: we don't increment i here, we'll overwrite this entry
424 the next time through. */
425 }
426 else if (p[0] == ':')
427 {
a06660f7
DJ
428 unsigned int gdb_id = strtoul (p + 1, &q, 16);
429 unsigned long thread_id;
430
64386c31
DJ
431 if (p == q)
432 goto err;
433 p = q;
434 if (p[0] != ';' && p[0] != 0)
435 goto err;
436
a06660f7
DJ
437 thread_id = gdb_id_to_thread_id (gdb_id);
438 if (thread_id)
439 resume_info[i].thread = thread_id;
440 else
441 goto err;
442
64386c31
DJ
443 i++;
444 }
445 }
446
447 resume_info[i] = default_action;
448
449 /* Still used in occasional places in the backend. */
450 if (n == 1 && resume_info[0].thread != -1)
451 cont_thread = resume_info[0].thread;
452 else
453 cont_thread = -1;
dc3f8883 454 set_desired_inferior (0);
64386c31
DJ
455
456 (*the_target->resume) (resume_info);
457
458 free (resume_info);
459
460 *signal = mywait (status, 1);
461 prepare_resume_reply (own_buf, *status, *signal);
462 return;
463
464err:
465 /* No other way to report an error... */
466 strcpy (own_buf, "");
467 free (resume_info);
468 return;
469}
470
471/* Handle all of the extended 'v' packets. */
472void
fc620387 473handle_v_requests (char *own_buf, char *status, int *signal)
64386c31
DJ
474{
475 if (strncmp (own_buf, "vCont;", 6) == 0)
476 {
477 handle_v_cont (own_buf, status, signal);
478 return;
479 }
480
481 if (strncmp (own_buf, "vCont?", 6) == 0)
482 {
483 strcpy (own_buf, "vCont;c;C;s;S");
484 return;
485 }
486
487 /* Otherwise we didn't know what packet it was. Say we didn't
488 understand it. */
489 own_buf[0] = 0;
490 return;
491}
492
493void
494myresume (int step, int sig)
495{
496 struct thread_resume resume_info[2];
497 int n = 0;
498
d592fa2f 499 if (step || sig || (cont_thread != 0 && cont_thread != -1))
64386c31
DJ
500 {
501 resume_info[0].thread
502 = ((struct inferior_list_entry *) current_inferior)->id;
503 resume_info[0].step = step;
504 resume_info[0].sig = sig;
505 resume_info[0].leave_stopped = 0;
506 n++;
507 }
508 resume_info[n].thread = -1;
509 resume_info[n].step = 0;
510 resume_info[n].sig = 0;
d592fa2f 511 resume_info[n].leave_stopped = (cont_thread != 0 && cont_thread != -1);
64386c31
DJ
512
513 (*the_target->resume) (resume_info);
514}
515
0729219d 516static int attached;
c906108c 517
dd24457d
DJ
518static void
519gdbserver_version (void)
520{
521 printf ("GNU gdbserver %s\n"
522 "Copyright (C) 2006 Free Software Foundation, Inc.\n"
523 "gdbserver is free software, covered by the GNU General Public License.\n"
524 "This gdbserver was configured as \"%s\"\n",
525 version, host_name);
526}
527
0bc68c49
DJ
528static void
529gdbserver_usage (void)
530{
dd24457d
DJ
531 printf ("Usage:\tgdbserver COMM PROG [ARGS ...]\n"
532 "\tgdbserver COMM --attach PID\n"
533 "\n"
534 "COMM may either be a tty device (for serial debugging), or \n"
535 "HOST:PORT to listen for a TCP connection.\n");
0bc68c49
DJ
536}
537
c906108c 538int
da85418c 539main (int argc, char *argv[])
c906108c 540{
f450004a 541 char ch, status, *own_buf;
7fb85e41 542 unsigned char *mem_buf;
c906108c 543 int i = 0;
fc620387 544 int signal;
c906108c
SS
545 unsigned int len;
546 CORE_ADDR mem_addr;
0729219d
DJ
547 int bad_attach;
548 int pid;
45b7b345 549 char *arg_end;
c906108c 550
dd24457d
DJ
551 if (argc >= 2 && strcmp (argv[1], "--version") == 0)
552 {
553 gdbserver_version ();
554 exit (0);
555 }
556
557 if (argc >= 2 && strcmp (argv[1], "--help") == 0)
558 {
559 gdbserver_usage ();
560 exit (0);
561 }
562
c5aa993b 563 if (setjmp (toplevel))
c906108c 564 {
c5aa993b
JM
565 fprintf (stderr, "Exiting\n");
566 exit (1);
c906108c
SS
567 }
568
0729219d
DJ
569 bad_attach = 0;
570 pid = 0;
571 attached = 0;
45b7b345
DJ
572 if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
573 {
574 if (argc == 4
575 && argv[3] != '\0'
576 && (pid = strtoul (argv[3], &arg_end, 10)) != 0
577 && *arg_end == '\0')
578 {
579 ;
580 }
581 else
582 bad_attach = 1;
583 }
584
585 if (argc < 3 || bad_attach)
dd24457d
DJ
586 {
587 gdbserver_usage ();
588 exit (1);
589 }
c906108c 590
4ce44c66
JM
591 initialize_low ();
592
0a30fbc4 593 own_buf = malloc (PBUFSIZ);
7fb85e41 594 mem_buf = malloc (PBUFSIZ);
0a30fbc4 595
45b7b345
DJ
596 if (pid == 0)
597 {
598 /* Wait till we are at first instruction in program. */
599 signal = start_inferior (&argv[2], &status);
c906108c 600
45b7b345
DJ
601 /* We are now stopped at the first instruction of the target process */
602 }
603 else
604 {
605 switch (attach_inferior (pid, &status, &signal))
606 {
607 case -1:
608 error ("Attaching not supported on this target");
609 break;
610 default:
611 attached = 1;
612 break;
613 }
614 }
c906108c 615
8264bb58
DJ
616 if (setjmp (toplevel))
617 {
618 fprintf (stderr, "Killing inferior\n");
619 kill_inferior ();
620 exit (1);
621 }
622
c906108c
SS
623 while (1)
624 {
625 remote_open (argv[1]);
626
c5aa993b
JM
627 restart:
628 setjmp (toplevel);
01f9e8fa 629 while (1)
c906108c
SS
630 {
631 unsigned char sig;
01f9e8fa
DJ
632 int packet_len;
633 int new_packet_len = -1;
634
635 packet_len = getpkt (own_buf);
636 if (packet_len <= 0)
637 break;
638
c906108c
SS
639 i = 0;
640 ch = own_buf[i++];
641 switch (ch)
642 {
ce3a066d 643 case 'q':
0876f84a 644 handle_query (own_buf, &new_packet_len);
ce3a066d 645 break;
89be2091
DJ
646 case 'Q':
647 handle_general_set (own_buf);
648 break;
c906108c
SS
649 case 'd':
650 remote_debug = !remote_debug;
651 break;
b80864fb
DJ
652#ifndef USE_WIN32API
653 /* Skip "detach" support on mingw32, since we don't have
654 waitpid. */
6ad8ae5c
DJ
655 case 'D':
656 fprintf (stderr, "Detaching from inferior\n");
657 detach_inferior ();
658 write_ok (own_buf);
659 putpkt (own_buf);
aa691b87 660 remote_close ();
6ad8ae5c
DJ
661
662 /* If we are attached, then we can exit. Otherwise, we need to
663 hang around doing nothing, until the child is gone. */
664 if (!attached)
665 {
666 int status, ret;
667
668 do {
669 ret = waitpid (signal_pid, &status, 0);
670 if (WIFEXITED (status) || WIFSIGNALED (status))
671 break;
672 } while (ret != -1 || errno != ECHILD);
673 }
674
675 exit (0);
b80864fb 676#endif
6ad8ae5c 677
c906108c 678 case '!':
45b7b345
DJ
679 if (attached == 0)
680 {
681 extended_protocol = 1;
682 prepare_resume_reply (own_buf, status, signal);
683 }
684 else
685 {
686 /* We can not use the extended protocol if we are
687 attached, because we can not restart the running
688 program. So return unrecognized. */
689 own_buf[0] = '\0';
690 }
c906108c
SS
691 break;
692 case '?':
693 prepare_resume_reply (own_buf, status, signal);
694 break;
695 case 'H':
a06660f7 696 if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
c906108c 697 {
a06660f7
DJ
698 unsigned long gdb_id, thread_id;
699
700 gdb_id = strtoul (&own_buf[2], NULL, 16);
701 thread_id = gdb_id_to_thread_id (gdb_id);
702 if (thread_id == 0)
703 {
704 write_enn (own_buf);
705 break;
706 }
707
708 if (own_buf[1] == 'g')
709 {
710 general_thread = thread_id;
711 set_desired_inferior (1);
712 }
713 else if (own_buf[1] == 'c')
714 cont_thread = thread_id;
715 else if (own_buf[1] == 's')
716 step_thread = thread_id;
717
0d62e5e8 718 write_ok (own_buf);
a06660f7
DJ
719 }
720 else
721 {
c906108c
SS
722 /* Silently ignore it so that gdb can extend the protocol
723 without compatibility headaches. */
724 own_buf[0] = '\0';
c906108c
SS
725 }
726 break;
727 case 'g':
0d62e5e8 728 set_desired_inferior (1);
0a30fbc4 729 registers_to_string (own_buf);
c906108c
SS
730 break;
731 case 'G':
0d62e5e8 732 set_desired_inferior (1);
0a30fbc4 733 registers_from_string (&own_buf[1]);
c906108c
SS
734 write_ok (own_buf);
735 break;
736 case 'm':
737 decode_m_packet (&own_buf[1], &mem_addr, &len);
c3e735a6
DJ
738 if (read_inferior_memory (mem_addr, mem_buf, len) == 0)
739 convert_int_to_ascii (mem_buf, own_buf, len);
740 else
741 write_enn (own_buf);
c906108c
SS
742 break;
743 case 'M':
744 decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
745 if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
746 write_ok (own_buf);
747 else
748 write_enn (own_buf);
749 break;
01f9e8fa
DJ
750 case 'X':
751 if (decode_X_packet (&own_buf[1], packet_len - 1,
752 &mem_addr, &len, mem_buf) < 0
753 || write_inferior_memory (mem_addr, mem_buf, len) != 0)
754 write_enn (own_buf);
755 else
756 write_ok (own_buf);
757 break;
c906108c
SS
758 case 'C':
759 convert_ascii_to_int (own_buf + 1, &sig, 1);
0e98d0a7
DJ
760 if (target_signal_to_host_p (sig))
761 signal = target_signal_to_host (sig);
762 else
763 signal = 0;
0d62e5e8 764 set_desired_inferior (0);
0e98d0a7 765 myresume (0, signal);
0d62e5e8 766 signal = mywait (&status, 1);
c906108c
SS
767 prepare_resume_reply (own_buf, status, signal);
768 break;
769 case 'S':
770 convert_ascii_to_int (own_buf + 1, &sig, 1);
0e98d0a7
DJ
771 if (target_signal_to_host_p (sig))
772 signal = target_signal_to_host (sig);
773 else
774 signal = 0;
0d62e5e8 775 set_desired_inferior (0);
0e98d0a7 776 myresume (1, signal);
0d62e5e8 777 signal = mywait (&status, 1);
c906108c
SS
778 prepare_resume_reply (own_buf, status, signal);
779 break;
780 case 'c':
0d62e5e8 781 set_desired_inferior (0);
c906108c 782 myresume (0, 0);
0d62e5e8 783 signal = mywait (&status, 1);
c906108c
SS
784 prepare_resume_reply (own_buf, status, signal);
785 break;
786 case 's':
0d62e5e8 787 set_desired_inferior (0);
c906108c 788 myresume (1, 0);
0d62e5e8 789 signal = mywait (&status, 1);
c906108c
SS
790 prepare_resume_reply (own_buf, status, signal);
791 break;
e013ee27
OF
792 case 'Z':
793 {
794 char *lenptr;
795 char *dataptr;
796 CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
797 int len = strtol (lenptr + 1, &dataptr, 16);
798 char type = own_buf[1];
799
800 if (the_target->insert_watchpoint == NULL
801 || (type < '2' || type > '4'))
802 {
803 /* No watchpoint support or not a watchpoint command;
804 unrecognized either way. */
805 own_buf[0] = '\0';
806 }
807 else
808 {
809 int res;
810
811 res = (*the_target->insert_watchpoint) (type, addr, len);
812 if (res == 0)
813 write_ok (own_buf);
814 else if (res == 1)
815 /* Unsupported. */
816 own_buf[0] = '\0';
817 else
818 write_enn (own_buf);
819 }
820 break;
821 }
822 case 'z':
823 {
824 char *lenptr;
825 char *dataptr;
826 CORE_ADDR addr = strtoul (&own_buf[3], &lenptr, 16);
827 int len = strtol (lenptr + 1, &dataptr, 16);
828 char type = own_buf[1];
829
830 if (the_target->remove_watchpoint == NULL
831 || (type < '2' || type > '4'))
832 {
833 /* No watchpoint support or not a watchpoint command;
834 unrecognized either way. */
835 own_buf[0] = '\0';
836 }
837 else
838 {
839 int res;
840
841 res = (*the_target->remove_watchpoint) (type, addr, len);
842 if (res == 0)
843 write_ok (own_buf);
844 else if (res == 1)
845 /* Unsupported. */
846 own_buf[0] = '\0';
847 else
848 write_enn (own_buf);
849 }
850 break;
851 }
c906108c
SS
852 case 'k':
853 fprintf (stderr, "Killing inferior\n");
854 kill_inferior ();
855 /* When using the extended protocol, we start up a new
c5aa993b 856 debugging session. The traditional protocol will
c906108c
SS
857 exit instead. */
858 if (extended_protocol)
859 {
860 write_ok (own_buf);
861 fprintf (stderr, "GDBserver restarting\n");
862
863 /* Wait till we are at 1st instruction in prog. */
864 signal = start_inferior (&argv[2], &status);
865 goto restart;
866 break;
867 }
868 else
869 {
870 exit (0);
871 break;
872 }
873 case 'T':
a06660f7
DJ
874 {
875 unsigned long gdb_id, thread_id;
876
877 gdb_id = strtoul (&own_buf[1], NULL, 16);
878 thread_id = gdb_id_to_thread_id (gdb_id);
879 if (thread_id == 0)
880 {
881 write_enn (own_buf);
882 break;
883 }
884
885 if (mythread_alive (thread_id))
886 write_ok (own_buf);
887 else
888 write_enn (own_buf);
889 }
c906108c
SS
890 break;
891 case 'R':
892 /* Restarting the inferior is only supported in the
c5aa993b 893 extended protocol. */
c906108c
SS
894 if (extended_protocol)
895 {
896 kill_inferior ();
897 write_ok (own_buf);
898 fprintf (stderr, "GDBserver restarting\n");
899
900 /* Wait till we are at 1st instruction in prog. */
901 signal = start_inferior (&argv[2], &status);
902 goto restart;
903 break;
904 }
905 else
906 {
907 /* It is a request we don't understand. Respond with an
908 empty packet so that gdb knows that we don't support this
909 request. */
910 own_buf[0] = '\0';
911 break;
912 }
64386c31
DJ
913 case 'v':
914 /* Extended (long) request. */
915 handle_v_requests (own_buf, &status, &signal);
916 break;
c906108c
SS
917 default:
918 /* It is a request we don't understand. Respond with an
c5aa993b
JM
919 empty packet so that gdb knows that we don't support this
920 request. */
c906108c
SS
921 own_buf[0] = '\0';
922 break;
923 }
924
01f9e8fa
DJ
925 if (new_packet_len != -1)
926 putpkt_binary (own_buf, new_packet_len);
927 else
928 putpkt (own_buf);
c906108c
SS
929
930 if (status == 'W')
931 fprintf (stderr,
3a7fb99b 932 "\nChild exited with status %d\n", signal);
c906108c 933 if (status == 'X')
b80864fb
DJ
934 fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
935 target_signal_to_host (signal),
936 target_signal_to_name (signal));
c906108c
SS
937 if (status == 'W' || status == 'X')
938 {
939 if (extended_protocol)
940 {
941 fprintf (stderr, "Killing inferior\n");
942 kill_inferior ();
943 write_ok (own_buf);
944 fprintf (stderr, "GDBserver restarting\n");
945
946 /* Wait till we are at 1st instruction in prog. */
947 signal = start_inferior (&argv[2], &status);
948 goto restart;
949 break;
950 }
951 else
952 {
953 fprintf (stderr, "GDBserver exiting\n");
954 exit (0);
955 }
956 }
957 }
958
959 /* We come here when getpkt fails.
960
c5aa993b
JM
961 For the extended remote protocol we exit (and this is the only
962 way we gracefully exit!).
c906108c 963
c5aa993b
JM
964 For the traditional remote protocol close the connection,
965 and re-open it at the top of the loop. */
c906108c
SS
966 if (extended_protocol)
967 {
968 remote_close ();
969 exit (0);
970 }
971 else
972 {
45b7b345
DJ
973 fprintf (stderr, "Remote side has terminated connection. "
974 "GDBserver will reopen the connection.\n");
c906108c
SS
975 remote_close ();
976 }
977 }
978}