2002-04-09 Daniel Jacobowitz <drow@mvista.com>
[external/binutils.git] / gdb / gdbserver / server.c
1 /* Main code for remote server for GDB.
2    Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "server.h"
23
24 int cont_thread;
25 int general_thread;
26 int thread_from_wait;
27 int old_thread_from_wait;
28 int extended_protocol;
29 jmp_buf toplevel;
30
31 static unsigned char
32 start_inferior (char *argv[], char *statusptr)
33 {
34   /* FIXME Check error? Or turn to void.  */
35   create_inferior (argv[0], argv);
36   /* FIXME Print pid properly.  */
37   fprintf (stderr, "Process %s created; pid = %d\n", argv[0], signal_pid);
38
39   /* Wait till we are at 1st instruction in program, return signal number.  */
40   return mywait (statusptr);
41 }
42
43 static int
44 attach_inferior (int pid, char *statusptr, unsigned char *sigptr)
45 {
46   /* myattach should return -1 if attaching is unsupported,
47      0 if it succeeded, and call error() otherwise.  */
48   if (myattach (pid) != 0)
49     return -1;
50
51   add_inferior (pid);
52
53   *sigptr = mywait (statusptr);
54
55   return 0;
56 }
57
58 extern int remote_debug;
59
60 /* Handle all of the extended 'q' packets.  */
61 void
62 handle_query (char *own_buf)
63 {
64   if (strcmp ("qSymbol::", own_buf) == 0)
65     {
66       if (the_target->look_up_symbols != NULL)
67         (*the_target->look_up_symbols) ();
68
69       strcpy (own_buf, "OK");
70       return;
71     }
72
73   /* Otherwise we didn't know what packet it was.  Say we didn't
74      understand it.  */
75   own_buf[0] = 0;
76 }
77
78 static int attached;
79
80 int
81 main (int argc, char *argv[])
82 {
83   char ch, status, *own_buf, mem_buf[2000];
84   int i = 0;
85   unsigned char signal;
86   unsigned int len;
87   CORE_ADDR mem_addr;
88   int bad_attach;
89   int pid;
90   char *arg_end;
91
92   if (setjmp (toplevel))
93     {
94       fprintf (stderr, "Exiting\n");
95       exit (1);
96     }
97
98   bad_attach = 0;
99   pid = 0;
100   attached = 0;
101   if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
102     {
103       if (argc == 4
104           && argv[3] != '\0'
105           && (pid = strtoul (argv[3], &arg_end, 10)) != 0
106           && *arg_end == '\0')
107         {
108           ;
109         }
110       else
111         bad_attach = 1;
112     }
113
114   if (argc < 3 || bad_attach)
115     error ("Usage:\tgdbserver tty prog [args ...]\n"
116                  "\tgdbserver tty --attach pid");
117
118   initialize_low ();
119
120   own_buf = malloc (PBUFSIZ);
121
122   if (pid == 0)
123     {
124       /* Wait till we are at first instruction in program.  */
125       signal = start_inferior (&argv[2], &status);
126
127       /* We are now stopped at the first instruction of the target process */
128     }
129   else
130     {
131       switch (attach_inferior (pid, &status, &signal))
132         {
133         case -1:
134           error ("Attaching not supported on this target");
135           break;
136         default:
137           attached = 1;
138           break;
139         }
140     }
141
142   while (1)
143     {
144       remote_open (argv[1]);
145
146     restart:
147       setjmp (toplevel);
148       while (getpkt (own_buf) > 0)
149         {
150           unsigned char sig;
151           i = 0;
152           ch = own_buf[i++];
153           switch (ch)
154             {
155             case 'q':
156               handle_query (own_buf);
157               break;
158             case 'd':
159               remote_debug = !remote_debug;
160               break;
161             case '!':
162               if (attached == 0)
163                 {
164                   extended_protocol = 1;
165                   prepare_resume_reply (own_buf, status, signal);
166                 }
167               else
168                 {
169                   /* We can not use the extended protocol if we are
170                      attached, because we can not restart the running
171                      program.  So return unrecognized.  */
172                   own_buf[0] = '\0';
173                 }
174               break;
175             case '?':
176               prepare_resume_reply (own_buf, status, signal);
177               break;
178             case 'H':
179               switch (own_buf[1])
180                 {
181                 case 'g':
182                   general_thread = strtol (&own_buf[2], NULL, 16);
183                   write_ok (own_buf);
184                   fetch_inferior_registers (0);
185                   break;
186                 case 'c':
187                   cont_thread = strtol (&own_buf[2], NULL, 16);
188                   write_ok (own_buf);
189                   break;
190                 default:
191                   /* Silently ignore it so that gdb can extend the protocol
192                      without compatibility headaches.  */
193                   own_buf[0] = '\0';
194                   break;
195                 }
196               break;
197             case 'g':
198               registers_to_string (own_buf);
199               break;
200             case 'G':
201               registers_from_string (&own_buf[1]);
202               store_inferior_registers (-1);
203               write_ok (own_buf);
204               break;
205             case 'm':
206               decode_m_packet (&own_buf[1], &mem_addr, &len);
207               read_inferior_memory (mem_addr, mem_buf, len);
208               convert_int_to_ascii (mem_buf, own_buf, len);
209               break;
210             case 'M':
211               decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
212               if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
213                 write_ok (own_buf);
214               else
215                 write_enn (own_buf);
216               break;
217             case 'C':
218               convert_ascii_to_int (own_buf + 1, &sig, 1);
219               if (target_signal_to_host_p (sig))
220                 signal = target_signal_to_host (sig);
221               else
222                 signal = 0;
223               myresume (0, signal);
224               signal = mywait (&status);
225               prepare_resume_reply (own_buf, status, signal);
226               break;
227             case 'S':
228               convert_ascii_to_int (own_buf + 1, &sig, 1);
229               if (target_signal_to_host_p (sig))
230                 signal = target_signal_to_host (sig);
231               else
232                 signal = 0;
233               myresume (1, signal);
234               signal = mywait (&status);
235               prepare_resume_reply (own_buf, status, signal);
236               break;
237             case 'c':
238               myresume (0, 0);
239               signal = mywait (&status);
240               prepare_resume_reply (own_buf, status, signal);
241               break;
242             case 's':
243               myresume (1, 0);
244               signal = mywait (&status);
245               prepare_resume_reply (own_buf, status, signal);
246               break;
247             case 'k':
248               fprintf (stderr, "Killing inferior\n");
249               kill_inferior ();
250               /* When using the extended protocol, we start up a new
251                  debugging session.   The traditional protocol will
252                  exit instead.  */
253               if (extended_protocol)
254                 {
255                   write_ok (own_buf);
256                   fprintf (stderr, "GDBserver restarting\n");
257
258                   /* Wait till we are at 1st instruction in prog.  */
259                   signal = start_inferior (&argv[2], &status);
260                   goto restart;
261                   break;
262                 }
263               else
264                 {
265                   exit (0);
266                   break;
267                 }
268             case 'T':
269               if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
270                 write_ok (own_buf);
271               else
272                 write_enn (own_buf);
273               break;
274             case 'R':
275               /* Restarting the inferior is only supported in the
276                  extended protocol.  */
277               if (extended_protocol)
278                 {
279                   kill_inferior ();
280                   write_ok (own_buf);
281                   fprintf (stderr, "GDBserver restarting\n");
282
283                   /* Wait till we are at 1st instruction in prog.  */
284                   signal = start_inferior (&argv[2], &status);
285                   goto restart;
286                   break;
287                 }
288               else
289                 {
290                   /* It is a request we don't understand.  Respond with an
291                      empty packet so that gdb knows that we don't support this
292                      request.  */
293                   own_buf[0] = '\0';
294                   break;
295                 }
296             default:
297               /* It is a request we don't understand.  Respond with an
298                  empty packet so that gdb knows that we don't support this
299                  request.  */
300               own_buf[0] = '\0';
301               break;
302             }
303
304           putpkt (own_buf);
305
306           if (status == 'W')
307             fprintf (stderr,
308                      "\nChild exited with status %d\n", sig);
309           if (status == 'X')
310             fprintf (stderr, "\nChild terminated with signal = 0x%x\n", sig);
311           if (status == 'W' || status == 'X')
312             {
313               if (extended_protocol)
314                 {
315                   fprintf (stderr, "Killing inferior\n");
316                   kill_inferior ();
317                   write_ok (own_buf);
318                   fprintf (stderr, "GDBserver restarting\n");
319
320                   /* Wait till we are at 1st instruction in prog.  */
321                   signal = start_inferior (&argv[2], &status);
322                   goto restart;
323                   break;
324                 }
325               else
326                 {
327                   fprintf (stderr, "GDBserver exiting\n");
328                   exit (0);
329                 }
330             }
331         }
332
333       /* We come here when getpkt fails.
334
335          For the extended remote protocol we exit (and this is the only
336          way we gracefully exit!).
337
338          For the traditional remote protocol close the connection,
339          and re-open it at the top of the loop.  */
340       if (extended_protocol)
341         {
342           remote_close ();
343           exit (0);
344         }
345       else
346         {
347           fprintf (stderr, "Remote side has terminated connection.  "
348                            "GDBserver will reopen the connection.\n");
349           remote_close ();
350         }
351     }
352 }