Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / gdb / gdb / gdbserver / server.c
1 /* Main code for remote server for GDB.
2    Copyright (C) 1989, 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "server.h"
21
22 int cont_thread;
23 int general_thread;
24 int thread_from_wait;
25 int old_thread_from_wait;
26 int extended_protocol;
27 jmp_buf toplevel;
28 int inferior_pid;
29
30 static unsigned char
31 start_inferior (argv, statusptr)
32      char *argv[];
33      char *statusptr;
34 {
35   inferior_pid = create_inferior (argv[0], argv);
36   fprintf (stderr, "Process %s created; pid = %d\n", argv[0], inferior_pid);
37
38   /* Wait till we are at 1st instruction in program, return signal number.  */
39   return mywait (statusptr);
40 }
41
42 extern int remote_debug;
43
44 int
45 main (argc, argv)
46      int argc;
47      char *argv[];
48 {
49   char ch, status, own_buf[2000], mem_buf[2000];
50   int i = 0;
51   unsigned char signal;
52   unsigned int len;
53   CORE_ADDR mem_addr;
54
55   if (setjmp(toplevel))
56     {
57       fprintf(stderr, "Exiting\n");
58       exit(1);
59     }
60
61   if (argc < 3)
62     error("Usage: gdbserver tty prog [args ...]");
63
64   /* Wait till we are at first instruction in program.  */
65   signal = start_inferior (&argv[2], &status);
66
67   /* We are now stopped at the first instruction of the target process */
68
69   while (1)
70     {
71       remote_open (argv[1]);
72
73 restart:
74       setjmp(toplevel);
75       while (getpkt (own_buf) > 0)
76         {
77           unsigned char sig;
78           i = 0;
79           ch = own_buf[i++];
80           switch (ch)
81             {
82             case 'd':
83               remote_debug = !remote_debug;
84               break;
85             case '!':
86               extended_protocol = 1;
87               prepare_resume_reply (own_buf, status, signal);
88               break;
89             case '?':
90               prepare_resume_reply (own_buf, status, signal);
91               break;
92             case 'H':
93               switch (own_buf[1])
94                 {
95                 case 'g':
96                   general_thread = strtol (&own_buf[2], NULL, 16);
97                   write_ok (own_buf);
98                   fetch_inferior_registers (0);
99                   break;
100                 case 'c':
101                   cont_thread = strtol (&own_buf[2], NULL, 16);
102                   write_ok (own_buf);
103                   break;
104                 default:
105                   /* Silently ignore it so that gdb can extend the protocol
106                      without compatibility headaches.  */
107                   own_buf[0] = '\0';
108                   break;
109                 }
110               break;
111             case 'g':
112               convert_int_to_ascii (registers, own_buf, REGISTER_BYTES);
113               break;
114             case 'G':
115               convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES);
116               store_inferior_registers (-1);
117               write_ok (own_buf);
118               break;
119             case 'm':
120               decode_m_packet (&own_buf[1], &mem_addr, &len);
121               read_inferior_memory (mem_addr, mem_buf, len);
122               convert_int_to_ascii (mem_buf, own_buf, len);
123               break;
124             case 'M':
125               decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
126               if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
127                 write_ok (own_buf);
128               else
129                 write_enn (own_buf);
130               break;
131             case 'C':
132               convert_ascii_to_int (own_buf + 1, &sig, 1);
133               myresume (0, sig);
134               signal = mywait (&status);
135               prepare_resume_reply (own_buf, status, signal);
136               break;
137             case 'S':
138               convert_ascii_to_int (own_buf + 1, &sig, 1);
139               myresume (1, sig);
140               signal = mywait (&status);
141               prepare_resume_reply (own_buf, status, signal);
142               break;
143             case 'c':
144               myresume (0, 0);
145               signal = mywait (&status);
146               prepare_resume_reply (own_buf, status, signal);
147               break;
148             case 's':
149               myresume (1, 0);
150               signal = mywait (&status);
151               prepare_resume_reply (own_buf, status, signal);
152               break;
153             case 'k':
154               fprintf (stderr, "Killing inferior\n");
155               kill_inferior ();
156               /* When using the extended protocol, we start up a new
157                  debugging session.   The traditional protocol will
158                  exit instead.  */
159               if (extended_protocol)
160                 {
161                   write_ok (own_buf);
162                   fprintf (stderr, "GDBserver restarting\n");
163
164                   /* Wait till we are at 1st instruction in prog.  */
165                   signal = start_inferior (&argv[2], &status);
166                   goto restart;
167                   break;
168                 }
169               else
170                 {
171                   exit (0);
172                   break;
173                 }
174             case 'T':
175               if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
176                 write_ok (own_buf);
177               else
178                 write_enn (own_buf);
179               break;
180             case 'R':
181               /* Restarting the inferior is only supported in the
182                  extended protocol.  */
183               if (extended_protocol)
184                 {
185                   kill_inferior ();
186                   write_ok (own_buf);
187                   fprintf (stderr, "GDBserver restarting\n");
188
189                   /* Wait till we are at 1st instruction in prog.  */
190                   signal = start_inferior (&argv[2], &status);
191                   goto restart;
192                   break;
193                 }
194               else
195                 {
196                   /* It is a request we don't understand.  Respond with an
197                      empty packet so that gdb knows that we don't support this
198                      request.  */
199                   own_buf[0] = '\0';
200                   break;
201                 }
202             default:
203               /* It is a request we don't understand.  Respond with an
204                  empty packet so that gdb knows that we don't support this
205                  request.  */
206               own_buf[0] = '\0';
207               break;
208             }
209
210           putpkt (own_buf);
211
212           if (status == 'W')
213             fprintf (stderr,
214                      "\nChild exited with status %d\n", sig);
215           if (status == 'X')
216             fprintf (stderr, "\nChild terminated with signal = 0x%x\n", sig);
217           if (status == 'W' || status == 'X')
218             {
219               if (extended_protocol)
220                 {
221                   fprintf (stderr, "Killing inferior\n");
222                   kill_inferior ();
223                   write_ok (own_buf);
224                   fprintf (stderr, "GDBserver restarting\n");
225
226                   /* Wait till we are at 1st instruction in prog.  */
227                   signal = start_inferior (&argv[2], &status);
228                   goto restart;
229                   break;
230                 }
231               else
232                 {
233                   fprintf (stderr, "GDBserver exiting\n");
234                   exit (0);
235                 }
236             }
237         }
238
239       /* We come here when getpkt fails.
240
241          For the extended remote protocol we exit (and this is the only
242          way we gracefully exit!).
243
244          For the traditional remote protocol close the connection,
245          and re-open it at the top of the loop.  */
246       if (extended_protocol)
247         {
248           remote_close ();
249           exit (0);
250         }
251       else
252         {
253           fprintf (stderr, "Remote side has terminated connection.  GDBserver will reopen the connection.\n");
254
255           remote_close ();
256         }
257     }
258 }