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