test of branches. please ignore.
[deliverable/binutils-gdb.git] / gdb / gdbserver / remote-utils.c
CommitLineData
e20520b8
SG
1/* Remote utility routines for the remote server for GDB.
2 Copyright (C) 1986, 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., 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>
38dc5e12
SG
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>
e20520b8
SG
34
35extern int remote_desc;
36extern int remote_debugging;
e20520b8
SG
37
38void remote_open ();
39void remote_send ();
40void putpkt ();
41void getpkt ();
42
43void write_ok ();
44void write_enn ();
45void convert_ascii_to_int ();
46void convert_int_to_ascii ();
47void prepare_resume_reply ();
48
49/* Open a connection to a remote debugger.
50 NAME is the filename used for communication. */
51
52void
53remote_open (name, from_tty)
54 char *name;
55 int from_tty;
56{
57 struct sgttyb sg;
58
59 remote_debugging = 0;
60
38dc5e12
SG
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;
e20520b8 98
38dc5e12
SG
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 }
e20520b8
SG
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
118static int
119fromhex (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
132static int
133tohex (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
146void
147remote_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
160void
161putpkt (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
196static int
197readchar ()
198{
38dc5e12
SG
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;
e20520b8
SG
217}
218
219/* Read a packet from the remote machine, with error checking,
220 and store it in BUF. */
221
222void
223getpkt (buf)
224 char *buf;
225{
226 char *bp;
38dc5e12
SG
227 unsigned char csum, c1, c2;
228 int c;
e20520b8
SG
229
230 while (1)
231 {
232 csum = 0;
38dc5e12 233
e20520b8
SG
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
260void
261write_ok (buf)
262 char *buf;
263{
264 buf[0] = 'O';
265 buf[1] = 'k';
266 buf[2] = '\0';
267}
268
269void
270write_enn (buf)
271 char *buf;
272{
273 buf[0] = 'E';
274 buf[1] = 'N';
275 buf[2] = 'N';
276 buf[3] = '\0';
277}
278
279void
280convert_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
298void
299convert_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
312static char *
313outreg(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
329void
330prepare_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
357void
358decode_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
381void
382decode_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}
This page took 0.049029 seconds and 4 git commands to generate.