* Rename files for 14-character limits:
[binutils-gdb.git] / gdb / gdbserver / remote-utils.c
1 /* Remote utility routines for the remote server for GDB.
2 Copyright (C) 1986, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "defs.h"
21 #include <stdio.h>
22 #include <signal.h>
23 #include <sys/wait.h>
24 #include <sys/ioctl.h>
25 #include <a.out.h>
26 #include <sys/file.h>
27 #include <sgtty.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <sys/socket.h>
31 #include <sys/types.h>
32 #include <netinet/tcp.h>
33 #include <sys/time.h>
34
35 extern int remote_desc;
36 extern int remote_debugging;
37
38 void remote_open ();
39 void remote_send ();
40 void putpkt ();
41 void getpkt ();
42
43 void write_ok ();
44 void write_enn ();
45 void convert_ascii_to_int ();
46 void convert_int_to_ascii ();
47 void prepare_resume_reply ();
48
49 /* Open a connection to a remote debugger.
50 NAME is the filename used for communication. */
51
52 void
53 remote_open (name, from_tty)
54 char *name;
55 int from_tty;
56 {
57 struct sgttyb sg;
58
59 remote_debugging = 0;
60
61 if (!strchr (name, ':'))
62 {
63 remote_desc = open (name, O_RDWR);
64 if (remote_desc < 0)
65 perror_with_name ("Could not open remote device");
66
67 ioctl (remote_desc, TIOCGETP, &sg);
68 sg.sg_flags = RAW;
69 ioctl (remote_desc, TIOCSETP, &sg);
70 }
71 else
72 {
73 char *port_str;
74 int port;
75 struct sockaddr_in sockaddr;
76 int tmp;
77
78 port_str = strchr (name, ':');
79
80 port = atoi (port_str + 1);
81
82 remote_desc = socket (PF_INET, SOCK_STREAM, 0);
83 if (remote_desc < 0)
84 perror_with_name ("Can't open socket");
85
86 /* Allow rapid reuse of this port. */
87 tmp = 1;
88 setsockopt (remote_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp,
89 sizeof(tmp));
90
91 /* Enable TCP keep alive process. */
92 tmp = 1;
93 setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
94
95 sockaddr.sin_family = PF_INET;
96 sockaddr.sin_port = htons(port);
97 sockaddr.sin_addr.s_addr = INADDR_ANY;
98
99 if (bind (remote_desc, &sockaddr, sizeof (sockaddr))
100 || listen (remote_desc, 1))
101 perror_with_name ("Can't bind address");
102
103 tmp = sizeof (sockaddr);
104 remote_desc = accept (remote_desc, &sockaddr, &tmp);
105 if (remote_desc == -1)
106 perror_with_name ("Accept failed");
107
108 tmp = 1;
109 setsockopt (remote_desc, 6, TCP_NODELAY, (char *)&tmp, sizeof(tmp));
110 }
111
112 fprintf (stderr, "Remote debugging using %s\n", name);
113 remote_debugging = 1;
114 }
115
116 /* Convert hex digit A to a number. */
117
118 static int
119 fromhex (a)
120 int a;
121 {
122 if (a >= '0' && a <= '9')
123 return a - '0';
124 else if (a >= 'a' && a <= 'f')
125 return a - 'a' + 10;
126 else
127 error ("Reply contains invalid hex digit");
128 }
129
130 /* Convert number NIB to a hex digit. */
131
132 static int
133 tohex (nib)
134 int nib;
135 {
136 if (nib < 10)
137 return '0' + nib;
138 else
139 return 'a' + nib - 10;
140 }
141
142 /* Send the command in BUF to the remote machine,
143 and read the reply into BUF.
144 Report an error if we get an error reply. */
145
146 void
147 remote_send (buf)
148 char *buf;
149 {
150 putpkt (buf);
151 getpkt (buf);
152
153 if (buf[0] == 'E')
154 error ("Remote failure reply: E");
155 }
156
157 /* Send a packet to the remote machine, with error checking.
158 The data of the packet is in BUF. */
159
160 void
161 putpkt (buf)
162 char *buf;
163 {
164 int i;
165 unsigned char csum = 0;
166 char buf2[2000];
167 char buf3[1];
168 int cnt = strlen (buf);
169 char *p;
170
171 /* Copy the packet into buffer BUF2, encapsulating it
172 and giving it a checksum. */
173
174 p = buf2;
175 *p++ = '$';
176
177 for (i = 0; i < cnt; i++)
178 {
179 csum += buf[i];
180 *p++ = buf[i];
181 }
182 *p++ = '#';
183 *p++ = tohex ((csum >> 4) & 0xf);
184 *p++ = tohex (csum & 0xf);
185
186 /* Send it over and over until we get a positive ack. */
187
188 do
189 {
190 write (remote_desc, buf2, p - buf2);
191 read (remote_desc, buf3, 1);
192 }
193 while (buf3[0] != '+');
194 }
195
196 static int
197 readchar ()
198 {
199 static char buf[BUFSIZ];
200 static int bufcnt = 0;
201 static char *bufp;
202
203 if (bufcnt-- > 0)
204 return *bufp++ & 0x7f;
205
206 bufcnt = read (remote_desc, buf, sizeof (buf));
207
208 if (bufcnt <= 0)
209 {
210 perror ("readchar");
211 fatal ("read error, quitting");
212 }
213
214 bufp = buf;
215 bufcnt--;
216 return *bufp++ & 0x7f;
217 }
218
219 /* Read a packet from the remote machine, with error checking,
220 and store it in BUF. */
221
222 void
223 getpkt (buf)
224 char *buf;
225 {
226 char *bp;
227 unsigned char csum, c1, c2;
228 int c;
229
230 while (1)
231 {
232 csum = 0;
233
234 while ((c = readchar ()) != '$');
235
236 bp = buf;
237 while (1)
238 {
239 c = readchar ();
240 if (c == '#')
241 break;
242 *bp++ = c;
243 csum += c;
244 }
245 *bp = 0;
246
247 c1 = fromhex (readchar ());
248 c2 = fromhex (readchar ());
249 if (csum == (c1 << 4) + c2)
250 break;
251
252 fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
253 (c1 << 4) + c2, csum, buf);
254 write (remote_desc, "-", 1);
255 }
256
257 write (remote_desc, "+", 1);
258 }
259
260 void
261 write_ok (buf)
262 char *buf;
263 {
264 buf[0] = 'O';
265 buf[1] = 'k';
266 buf[2] = '\0';
267 }
268
269 void
270 write_enn (buf)
271 char *buf;
272 {
273 buf[0] = 'E';
274 buf[1] = 'N';
275 buf[2] = 'N';
276 buf[3] = '\0';
277 }
278
279 void
280 convert_int_to_ascii (from, to, n)
281 char *from, *to;
282 int n;
283 {
284 int nib;
285 char ch;
286 while (n--)
287 {
288 ch = *from++;
289 nib = ((ch & 0xf0) >> 4) & 0x0f;
290 *to++ = tohex (nib);
291 nib = ch & 0x0f;
292 *to++ = tohex (nib);
293 }
294 *to++ = 0;
295 }
296
297
298 void
299 convert_ascii_to_int (from, to, n)
300 char *from, *to;
301 int n;
302 {
303 int nib1, nib2;
304 while (n--)
305 {
306 nib1 = fromhex (*from++);
307 nib2 = fromhex (*from++);
308 *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
309 }
310 }
311
312 static char *
313 outreg(regno, buf)
314 int regno;
315 char *buf;
316 {
317 extern char registers[];
318
319 *buf++ = tohex (regno >> 4);
320 *buf++ = tohex (regno & 0xf);
321 *buf++ = ':';
322 convert_int_to_ascii (&registers[REGISTER_BYTE (regno)], buf, 4);
323 buf += 8;
324 *buf++ = ';';
325
326 return buf;
327 }
328
329 void
330 prepare_resume_reply (buf, status, signal)
331 char *buf, status;
332 unsigned char signal;
333 {
334 int nib;
335 char ch;
336
337 *buf++ = 'T';
338
339 nib = ((signal & 0xf0) >> 4);
340 *buf++ = tohex (nib);
341 nib = signal & 0x0f;
342 *buf++ = tohex (nib);
343
344 buf = outreg (PC_REGNUM, buf);
345 buf = outreg (FP_REGNUM, buf);
346 buf = outreg (SP_REGNUM, buf);
347 #ifdef NPC_REGNUM
348 buf = outreg (NPC_REGNUM, buf);
349 #endif
350 #ifdef O7_REGNUM
351 buf = outreg (O7_REGNUM, buf);
352 #endif
353
354 *buf++ = 0;
355 }
356
357 void
358 decode_m_packet (from, mem_addr_ptr, len_ptr)
359 char *from;
360 unsigned int *mem_addr_ptr, *len_ptr;
361 {
362 int i = 0, j = 0;
363 char ch;
364 *mem_addr_ptr = *len_ptr = 0;
365
366 while ((ch = from[i++]) != ',')
367 {
368 *mem_addr_ptr = *mem_addr_ptr << 4;
369 *mem_addr_ptr |= fromhex (ch) & 0x0f;
370 }
371
372 for (j = 0; j < 4; j++)
373 {
374 if ((ch = from[i++]) == 0)
375 break;
376 *len_ptr = *len_ptr << 4;
377 *len_ptr |= fromhex (ch) & 0x0f;
378 }
379 }
380
381 void
382 decode_M_packet (from, mem_addr_ptr, len_ptr, to)
383 char *from, *to;
384 unsigned int *mem_addr_ptr, *len_ptr;
385 {
386 int i = 0, j = 0;
387 char ch;
388 *mem_addr_ptr = *len_ptr = 0;
389
390 while ((ch = from[i++]) != ',')
391 {
392 *mem_addr_ptr = *mem_addr_ptr << 4;
393 *mem_addr_ptr |= fromhex (ch) & 0x0f;
394 }
395
396 while ((ch = from[i++]) != ':')
397 {
398 *len_ptr = *len_ptr << 4;
399 *len_ptr |= fromhex (ch) & 0x0f;
400 }
401
402 convert_ascii_to_int (&from[i++], to, *len_ptr);
403 }