import gdb-1999-07-07 post reformat
[deliverable/binutils-gdb.git] / gdb / gdbserver / server.c
CommitLineData
c906108c
SS
1/* Main code for remote server for GDB.
2 Copyright (C) 1989, 1993 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20#include "server.h"
21
22int cont_thread;
23int general_thread;
24int thread_from_wait;
25int old_thread_from_wait;
26int extended_protocol;
27jmp_buf toplevel;
28int inferior_pid;
29
30static unsigned char
31start_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
42extern int remote_debug;
43
44int
45main (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
73restart:
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}
This page took 0.038157 seconds and 4 git commands to generate.