2002-04-09 Daniel Jacobowitz <drow@mvista.com>
[deliverable/binutils-gdb.git] / gdb / gdbserver / server.c
CommitLineData
c906108c 1/* Main code for remote server for GDB.
db728ff7 2 Copyright 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2002
b6ba6518 3 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
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c
SS
21
22#include "server.h"
23
24int cont_thread;
25int general_thread;
26int thread_from_wait;
27int old_thread_from_wait;
28int extended_protocol;
29jmp_buf toplevel;
c906108c
SS
30
31static unsigned char
da85418c 32start_inferior (char *argv[], char *statusptr)
c906108c 33{
ce3a066d
DJ
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);
c906108c
SS
38
39 /* Wait till we are at 1st instruction in program, return signal number. */
40 return mywait (statusptr);
41}
42
45b7b345
DJ
43static int
44attach_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
ce3a066d 51 add_inferior (pid);
45b7b345
DJ
52
53 *sigptr = mywait (statusptr);
54
55 return 0;
56}
57
c906108c 58extern int remote_debug;
ce3a066d
DJ
59
60/* Handle all of the extended 'q' packets. */
61void
62handle_query (char *own_buf)
63{
64 if (strcmp ("qSymbol::", own_buf) == 0)
65 {
2f2893d9
DJ
66 if (the_target->look_up_symbols != NULL)
67 (*the_target->look_up_symbols) ();
68
ce3a066d
DJ
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
0729219d 78static int attached;
c906108c
SS
79
80int
da85418c 81main (int argc, char *argv[])
c906108c 82{
0a30fbc4 83 char ch, status, *own_buf, mem_buf[2000];
c906108c
SS
84 int i = 0;
85 unsigned char signal;
86 unsigned int len;
87 CORE_ADDR mem_addr;
0729219d
DJ
88 int bad_attach;
89 int pid;
45b7b345 90 char *arg_end;
c906108c 91
c5aa993b 92 if (setjmp (toplevel))
c906108c 93 {
c5aa993b
JM
94 fprintf (stderr, "Exiting\n");
95 exit (1);
c906108c
SS
96 }
97
0729219d
DJ
98 bad_attach = 0;
99 pid = 0;
100 attached = 0;
45b7b345
DJ
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");
c906108c 117
4ce44c66
JM
118 initialize_low ();
119
0a30fbc4
DJ
120 own_buf = malloc (PBUFSIZ);
121
45b7b345
DJ
122 if (pid == 0)
123 {
124 /* Wait till we are at first instruction in program. */
125 signal = start_inferior (&argv[2], &status);
c906108c 126
45b7b345
DJ
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 }
c906108c
SS
141
142 while (1)
143 {
144 remote_open (argv[1]);
145
c5aa993b
JM
146 restart:
147 setjmp (toplevel);
c906108c
SS
148 while (getpkt (own_buf) > 0)
149 {
150 unsigned char sig;
151 i = 0;
152 ch = own_buf[i++];
153 switch (ch)
154 {
ce3a066d
DJ
155 case 'q':
156 handle_query (own_buf);
157 break;
c906108c
SS
158 case 'd':
159 remote_debug = !remote_debug;
160 break;
161 case '!':
45b7b345
DJ
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 }
c906108c
SS
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':
0a30fbc4 198 registers_to_string (own_buf);
c906108c
SS
199 break;
200 case 'G':
0a30fbc4 201 registers_from_string (&own_buf[1]);
c906108c
SS
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);
0e98d0a7
DJ
219 if (target_signal_to_host_p (sig))
220 signal = target_signal_to_host (sig);
221 else
222 signal = 0;
223 myresume (0, signal);
c906108c
SS
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);
0e98d0a7
DJ
229 if (target_signal_to_host_p (sig))
230 signal = target_signal_to_host (sig);
231 else
232 signal = 0;
233 myresume (1, signal);
c906108c
SS
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
c5aa993b 251 debugging session. The traditional protocol will
c906108c
SS
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
c5aa993b 276 extended protocol. */
c906108c
SS
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
c5aa993b
JM
298 empty packet so that gdb knows that we don't support this
299 request. */
c906108c
SS
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
c5aa993b
JM
335 For the extended remote protocol we exit (and this is the only
336 way we gracefully exit!).
c906108c 337
c5aa993b
JM
338 For the traditional remote protocol close the connection,
339 and re-open it at the top of the loop. */
c906108c
SS
340 if (extended_protocol)
341 {
342 remote_close ();
343 exit (0);
344 }
345 else
346 {
45b7b345
DJ
347 fprintf (stderr, "Remote side has terminated connection. "
348 "GDBserver will reopen the connection.\n");
c906108c
SS
349 remote_close ();
350 }
351 }
352}
This page took 0.177535 seconds and 4 git commands to generate.