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