xref: /openbsd-src/gnu/usr.bin/binutils/gdb/gdbserver/remote-utils.c (revision a4afd6dad3fba28f80e70208181c06c482259988)
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19 
20 #include "server.h"
21 #include <stdio.h>
22 #include <sys/ioctl.h>
23 #include <sys/file.h>
24 #include <netinet/in.h>
25 #include <sys/socket.h>
26 #include <netdb.h>
27 #include <netinet/tcp.h>
28 #include <sys/ioctl.h>
29 #include <signal.h>
30 
31 static int kiodebug = 0;
32 static int remote_desc;
33 
34 /* Open a connection to a remote debugger.
35    NAME is the filename used for communication.  */
36 
37 void
38 remote_open (name)
39      char *name;
40 {
41   if (!strchr (name, ':'))
42     {
43       remote_desc = open (name, O_RDWR);
44       if (remote_desc < 0)
45 	perror_with_name ("Could not open remote device");
46 
47 #ifdef HAVE_TERMIOS
48       {
49 	struct termios termios;
50 	tcgetattr(remote_desc, &termios);
51 
52 	termios.c_iflag = 0;
53 	termios.c_oflag = 0;
54 	termios.c_lflag = 0;
55 	termios.c_cflag &= ~(CSIZE|PARENB);
56 	termios.c_cflag |= CLOCAL | CS8;
57 	termios.c_cc[VMIN] = 0;
58 	termios.c_cc[VTIME] = 0;
59 
60 	tcsetattr(remote_desc, TCSANOW, &termios);
61       }
62 #endif
63 
64 #ifdef HAVE_TERMIO
65       {
66 	struct termio termio;
67 	ioctl (remote_desc, TCGETA, &termio);
68 
69 	termio.c_iflag = 0;
70 	termio.c_oflag = 0;
71 	termio.c_lflag = 0;
72 	termio.c_cflag &= ~(CSIZE|PARENB);
73 	termio.c_cflag |= CLOCAL | CS8;
74 	termio.c_cc[VMIN] = 0;
75 	termio.c_cc[VTIME] = 0;
76 
77 	ioctl (remote_desc, TCSETA, &termio);
78       }
79 #endif
80 
81 #ifdef HAVE_SGTTY
82       {
83 	struct sgttyb sg;
84 
85 	ioctl (remote_desc, TIOCGETP, &sg);
86 	sg.sg_flags = RAW;
87 	ioctl (remote_desc, TIOCSETP, &sg);
88       }
89 #endif
90 
91 
92     }
93   else
94     {
95       char *port_str;
96       int port;
97       struct sockaddr_in sockaddr;
98       int tmp;
99       struct protoent *protoent;
100       int tmp_desc;
101 
102       port_str = strchr (name, ':');
103 
104       port = atoi (port_str + 1);
105 
106       tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
107       if (tmp_desc < 0)
108 	perror_with_name ("Can't open socket");
109 
110       /* Allow rapid reuse of this port. */
111       tmp = 1;
112       setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp,
113 		  sizeof(tmp));
114 
115       sockaddr.sin_family = PF_INET;
116       sockaddr.sin_port = htons(port);
117       sockaddr.sin_addr.s_addr = INADDR_ANY;
118 
119       if (bind (tmp_desc, (struct sockaddr *)&sockaddr, sizeof (sockaddr))
120 	  || listen (tmp_desc, 1))
121 	perror_with_name ("Can't bind address");
122 
123       tmp = sizeof (sockaddr);
124       remote_desc = accept (tmp_desc, (struct sockaddr *)&sockaddr, &tmp);
125       if (remote_desc == -1)
126 	perror_with_name ("Accept failed");
127 
128       protoent = getprotobyname ("tcp");
129       if (!protoent)
130 	perror_with_name ("getprotobyname");
131 
132       /* Enable TCP keep alive process. */
133       tmp = 1;
134       setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
135 
136       /* Tell TCP not to delay small packets.  This greatly speeds up
137 	 interactive response. */
138       tmp = 1;
139       setsockopt (remote_desc, protoent->p_proto, TCP_NODELAY,
140 		  (char *)&tmp, sizeof(tmp));
141 
142       close (tmp_desc);		/* No longer need this */
143 
144       signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
145 				    exits when the remote side dies.  */
146     }
147 
148   fcntl (remote_desc, F_SETFL, FASYNC);
149 
150   fprintf (stderr, "Remote debugging using %s\n", name);
151 }
152 
153 void
154 remote_close()
155 {
156   close (remote_desc);
157 }
158 
159 /* Convert hex digit A to a number.  */
160 
161 static int
162 fromhex (a)
163      int a;
164 {
165   if (a >= '0' && a <= '9')
166     return a - '0';
167   else if (a >= 'a' && a <= 'f')
168     return a - 'a' + 10;
169   else
170     error ("Reply contains invalid hex digit");
171 }
172 
173 /* Convert number NIB to a hex digit.  */
174 
175 static int
176 tohex (nib)
177      int nib;
178 {
179   if (nib < 10)
180     return '0' + nib;
181   else
182     return 'a' + nib - 10;
183 }
184 
185 /* Send a packet to the remote machine, with error checking.
186    The data of the packet is in BUF.  Returns >= 0 on success, -1 otherwise. */
187 
188 int
189 putpkt (buf)
190      char *buf;
191 {
192   int i;
193   unsigned char csum = 0;
194   char buf2[2000];
195   char buf3[1];
196   int cnt = strlen (buf);
197   char *p;
198 
199   /* Copy the packet into buffer BUF2, encapsulating it
200      and giving it a checksum.  */
201 
202   p = buf2;
203   *p++ = '$';
204 
205   for (i = 0; i < cnt; i++)
206     {
207       csum += buf[i];
208       *p++ = buf[i];
209     }
210   *p++ = '#';
211   *p++ = tohex ((csum >> 4) & 0xf);
212   *p++ = tohex (csum & 0xf);
213 
214   /* Send it over and over until we get a positive ack.  */
215 
216   do
217     {
218       int cc;
219 
220       if (write (remote_desc, buf2, p - buf2) != p - buf2)
221 	{
222 	  perror ("putpkt(write)");
223 	  return -1;
224 	}
225 
226       cc = read (remote_desc, buf3, 1);
227       if (cc <= 0)
228 	{
229 	  if (cc == 0)
230 	    fprintf (stderr, "putpkt(read): Got EOF\n");
231 	  else
232 	    perror ("putpkt(read)");
233 
234 	  return -1;
235 	}
236     }
237   while (buf3[0] != '+');
238 
239   return 1;			/* Success! */
240 }
241 
242 /* Come here when we get an input interrupt from the remote side.  This
243    interrupt should only be active while we are waiting for the child to do
244    something.  About the only thing that should come through is a ^C, which
245    will cause us to send a SIGINT to the child.  */
246 
247 static void
248 input_interrupt()
249 {
250   int cc;
251   char c;
252 
253   cc = read (remote_desc, &c, 1);
254 
255   if (cc != 1 || c != '\003')
256     {
257       fprintf(stderr, "input_interrupt, cc = %d c = %d\n", cc, c);
258       return;
259     }
260 
261   kill (inferior_pid, SIGINT);
262 }
263 
264 void
265 enable_async_io()
266 {
267   signal (SIGIO, input_interrupt);
268 }
269 
270 void
271 disable_async_io()
272 {
273   signal (SIGIO, SIG_IGN);
274 }
275 
276 /* Returns next char from remote GDB.  -1 if error.  */
277 
278 static int
279 readchar ()
280 {
281   static char buf[BUFSIZ];
282   static int bufcnt = 0;
283   static char *bufp;
284 
285   if (bufcnt-- > 0)
286     return *bufp++ & 0x7f;
287 
288   bufcnt = read (remote_desc, buf, sizeof (buf));
289 
290   if (bufcnt <= 0)
291     {
292       if (bufcnt == 0)
293 	fprintf (stderr, "readchar: Got EOF\n");
294       else
295 	perror ("readchar");
296 
297       return -1;
298     }
299 
300   bufp = buf;
301   bufcnt--;
302   return *bufp++ & 0x7f;
303 }
304 
305 /* Read a packet from the remote machine, with error checking,
306    and store it in BUF.  Returns length of packet, or negative if error. */
307 
308 int
309 getpkt (buf)
310      char *buf;
311 {
312   char *bp;
313   unsigned char csum, c1, c2;
314   int c;
315 
316   while (1)
317     {
318       csum = 0;
319 
320       while (1)
321 	{
322 	  c = readchar ();
323 	  if (c == '$')
324 	    break;
325 	  if (c < 0)
326 	    return -1;
327 	}
328 
329       bp = buf;
330       while (1)
331 	{
332 	  c = readchar ();
333 	  if (c < 0)
334 	    return -1;
335 	  if (c == '#')
336 	    break;
337 	  *bp++ = c;
338 	  csum += c;
339 	}
340       *bp = 0;
341 
342       c1 = fromhex (readchar ());
343       c2 = fromhex (readchar ());
344       if (csum == (c1 << 4) + c2)
345 	break;
346 
347       fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
348 	       (c1 << 4) + c2, csum, buf);
349       write (remote_desc, "-", 1);
350     }
351 
352   write (remote_desc, "+", 1);
353   return bp - buf;
354 }
355 
356 void
357 write_ok (buf)
358      char *buf;
359 {
360   buf[0] = 'O';
361   buf[1] = 'K';
362   buf[2] = '\0';
363 }
364 
365 void
366 write_enn (buf)
367      char *buf;
368 {
369   buf[0] = 'E';
370   buf[1] = 'N';
371   buf[2] = 'N';
372   buf[3] = '\0';
373 }
374 
375 void
376 convert_int_to_ascii (from, to, n)
377      char *from, *to;
378      int n;
379 {
380   int nib;
381   char ch;
382   while (n--)
383     {
384       ch = *from++;
385       nib = ((ch & 0xf0) >> 4) & 0x0f;
386       *to++ = tohex (nib);
387       nib = ch & 0x0f;
388       *to++ = tohex (nib);
389     }
390   *to++ = 0;
391 }
392 
393 
394 void
395 convert_ascii_to_int (from, to, n)
396      char *from, *to;
397      int n;
398 {
399   int nib1, nib2;
400   while (n--)
401     {
402       nib1 = fromhex (*from++);
403       nib2 = fromhex (*from++);
404       *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
405     }
406 }
407 
408 static char *
409 outreg(regno, buf)
410      int regno;
411      char *buf;
412 {
413   extern char registers[];
414 
415   *buf++ = tohex (regno >> 4);
416   *buf++ = tohex (regno & 0xf);
417   *buf++ = ':';
418   convert_int_to_ascii (&registers[REGISTER_BYTE (regno)], buf, 4);
419   buf += 8;
420   *buf++ = ';';
421 
422   return buf;
423 }
424 
425 void
426 prepare_resume_reply (buf, status, signal)
427      char *buf;
428      char status;
429      unsigned char signal;
430 {
431   int nib;
432   char ch;
433 
434   *buf++ = status;
435 
436   /* FIXME!  Should be converting this signal number (numbered
437      according to the signal numbering of the system we are running on)
438      to the signal numbers used by the gdb protocol (see enum target_signal
439      in gdb/target.h).  */
440   nib = ((signal & 0xf0) >> 4);
441   *buf++ = tohex (nib);
442   nib = signal & 0x0f;
443   *buf++ = tohex (nib);
444 
445   if (status == 'T')
446     {
447       buf = outreg (PC_REGNUM, buf);
448       buf = outreg (FP_REGNUM, buf);
449       buf = outreg (SP_REGNUM, buf);
450 #ifdef NPC_REGNUM
451       buf = outreg (NPC_REGNUM, buf);
452 #endif
453 #ifdef O7_REGNUM
454       buf = outreg (O7_REGNUM, buf);
455 #endif
456 
457       /* If the debugger hasn't used any thread features, don't burden it with
458 	 threads.  If we didn't check this, GDB 4.13 and older would choke.  */
459       if (cont_thread != 0)
460 	{
461 	  if (old_thread_from_wait != thread_from_wait)
462 	    {
463 	      sprintf (buf, "thread:%x;", thread_from_wait);
464 	      buf += strlen (buf);
465 	      old_thread_from_wait = thread_from_wait;
466 	    }
467 	}
468     }
469   /* For W and X, we're done.  */
470   *buf++ = 0;
471 }
472 
473 void
474 decode_m_packet (from, mem_addr_ptr, len_ptr)
475      char *from;
476      unsigned int *mem_addr_ptr, *len_ptr;
477 {
478   int i = 0, j = 0;
479   char ch;
480   *mem_addr_ptr = *len_ptr = 0;
481 
482   while ((ch = from[i++]) != ',')
483     {
484       *mem_addr_ptr = *mem_addr_ptr << 4;
485       *mem_addr_ptr |= fromhex (ch) & 0x0f;
486     }
487 
488   for (j = 0; j < 4; j++)
489     {
490       if ((ch = from[i++]) == 0)
491 	break;
492       *len_ptr = *len_ptr << 4;
493       *len_ptr |= fromhex (ch) & 0x0f;
494     }
495 }
496 
497 void
498 decode_M_packet (from, mem_addr_ptr, len_ptr, to)
499      char *from, *to;
500      unsigned int *mem_addr_ptr, *len_ptr;
501 {
502   int i = 0, j = 0;
503   char ch;
504   *mem_addr_ptr = *len_ptr = 0;
505 
506   while ((ch = from[i++]) != ',')
507     {
508       *mem_addr_ptr = *mem_addr_ptr << 4;
509       *mem_addr_ptr |= fromhex (ch) & 0x0f;
510     }
511 
512   while ((ch = from[i++]) != ':')
513     {
514       *len_ptr = *len_ptr << 4;
515       *len_ptr |= fromhex (ch) & 0x0f;
516     }
517 
518   convert_ascii_to_int (&from[i++], to, *len_ptr);
519 }
520