]> Git Repo - binutils.git/blob - gdb/gdbserver/remote-utils.c
* gdbserver/{remote-gutils.c remote-server.c Makefile.in
[binutils.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
29 extern int remote_desc;
30 extern int remote_debugging;
31 extern int kiodebug;
32
33 void remote_open ();
34 void remote_send ();
35 void putpkt ();
36 void getpkt ();
37
38 void write_ok ();
39 void write_enn ();
40 void convert_ascii_to_int ();
41 void convert_int_to_ascii ();
42 void prepare_resume_reply ();
43
44 /* Open a connection to a remote debugger.
45    NAME is the filename used for communication.  */
46
47 void
48 remote_open (name, from_tty)
49      char *name;
50      int from_tty;
51 {
52   struct sgttyb sg;
53
54   remote_debugging = 0;
55
56   remote_desc = open (name, O_RDWR);
57   if (remote_desc < 0)
58     perror_with_name ("Could not open remote device");
59
60   ioctl (remote_desc, TIOCGETP, &sg);
61   sg.sg_flags = RAW;
62   ioctl (remote_desc, TIOCSETP, &sg);
63
64   fprintf (stderr, "Remote debugging using %s\n", name);
65   remote_debugging = 1;
66 }
67
68 /* Convert hex digit A to a number.  */
69
70 static int
71 fromhex (a)
72      int a;
73 {
74   if (a >= '0' && a <= '9')
75     return a - '0';
76   else if (a >= 'a' && a <= 'f')
77     return a - 'a' + 10;
78   else
79     error ("Reply contains invalid hex digit");
80 }
81
82 /* Convert number NIB to a hex digit.  */
83
84 static int
85 tohex (nib)
86      int nib;
87 {
88   if (nib < 10)
89     return '0' + nib;
90   else
91     return 'a' + nib - 10;
92 }
93
94 /* Send the command in BUF to the remote machine,
95    and read the reply into BUF.
96    Report an error if we get an error reply.  */
97
98 void
99 remote_send (buf)
100      char *buf;
101 {
102   putpkt (buf);
103   getpkt (buf);
104
105   if (buf[0] == 'E')
106     error ("Remote failure reply: E");
107 }
108
109 /* Send a packet to the remote machine, with error checking.
110    The data of the packet is in BUF.  */
111
112 void
113 putpkt (buf)
114      char *buf;
115 {
116   int i;
117   unsigned char csum = 0;
118   char buf2[2000];
119   char buf3[1];
120   int cnt = strlen (buf);
121   char *p;
122
123   /* Copy the packet into buffer BUF2, encapsulating it
124      and giving it a checksum.  */
125
126   p = buf2;
127   *p++ = '$';
128
129   for (i = 0; i < cnt; i++)
130     {
131       csum += buf[i];
132       *p++ = buf[i];
133     }
134   *p++ = '#';
135   *p++ = tohex ((csum >> 4) & 0xf);
136   *p++ = tohex (csum & 0xf);
137
138   /* Send it over and over until we get a positive ack.  */
139
140   do
141     {
142       write (remote_desc, buf2, p - buf2);
143       read (remote_desc, buf3, 1);
144     }
145   while (buf3[0] != '+');
146 }
147
148 static int
149 readchar ()
150 {
151   char buf[1];
152   while (read (remote_desc, buf, 1) != 1);
153   return buf[0] & 0x7f;
154 }
155
156 /* Read a packet from the remote machine, with error checking,
157    and store it in BUF.  */
158
159 void
160 getpkt (buf)
161      char *buf;
162 {
163   char *bp;
164   unsigned char csum, c, c1, c2;
165   extern kiodebug;
166
167   while (1)
168     {
169       csum = 0;
170       while ((c = readchar ()) != '$');
171
172       bp = buf;
173       while (1)
174         {
175           c = readchar ();
176           if (c == '#')
177             break;
178           *bp++ = c;
179           csum += c;
180         }
181       *bp = 0;
182
183       c1 = fromhex (readchar ());
184       c2 = fromhex (readchar ());
185       if (csum == (c1 << 4) + c2)
186         break;
187
188       fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
189                (c1 << 4) + c2, csum, buf);
190       write (remote_desc, "-", 1);
191     }
192
193   write (remote_desc, "+", 1);
194 }
195
196 void
197 write_ok (buf)
198      char *buf;
199 {
200   buf[0] = 'O';
201   buf[1] = 'k';
202   buf[2] = '\0';
203 }
204
205 void
206 write_enn (buf)
207      char *buf;
208 {
209   buf[0] = 'E';
210   buf[1] = 'N';
211   buf[2] = 'N';
212   buf[3] = '\0';
213 }
214
215 void
216 convert_int_to_ascii (from, to, n)
217      char *from, *to;
218      int n;
219 {
220   int nib;
221   char ch;
222   while (n--)
223     {
224       ch = *from++;
225       nib = ((ch & 0xf0) >> 4) & 0x0f;
226       *to++ = tohex (nib);
227       nib = ch & 0x0f;
228       *to++ = tohex (nib);
229     }
230   *to++ = 0;
231 }
232
233
234 void
235 convert_ascii_to_int (from, to, n)
236      char *from, *to;
237      int n;
238 {
239   int nib1, nib2;
240   while (n--)
241     {
242       nib1 = fromhex (*from++);
243       nib2 = fromhex (*from++);
244       *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
245     }
246 }
247
248 static char *
249 outreg(regno, buf)
250      int regno;
251      char *buf;
252 {
253   extern char registers[];
254
255   *buf++ = tohex (regno >> 4);
256   *buf++ = tohex (regno & 0xf);
257   *buf++ = ':';
258   convert_int_to_ascii (&registers[REGISTER_BYTE (regno)], buf, 4);
259   buf += 8;
260   *buf++ = ';';
261
262   return buf;
263 }
264
265 void
266 prepare_resume_reply (buf, status, signal)
267      char *buf, status;
268      unsigned char signal;
269 {
270   int nib;
271   char ch;
272
273   *buf++ = 'T';
274
275   nib = ((signal & 0xf0) >> 4);
276   *buf++ = tohex (nib);
277   nib = signal & 0x0f;
278   *buf++ = tohex (nib);
279
280   buf = outreg (PC_REGNUM, buf);
281   buf = outreg (FP_REGNUM, buf);
282   buf = outreg (SP_REGNUM, buf);
283 #ifdef NPC_REGNUM
284   buf = outreg (NPC_REGNUM, buf);
285 #endif
286 #ifdef O7_REGNUM
287   buf = outreg (O7_REGNUM, buf);
288 #endif
289
290   *buf++ = 0;
291 }
292
293 void
294 decode_m_packet (from, mem_addr_ptr, len_ptr)
295      char *from;
296      unsigned int *mem_addr_ptr, *len_ptr;
297 {
298   int i = 0, j = 0;
299   char ch;
300   *mem_addr_ptr = *len_ptr = 0;
301
302   while ((ch = from[i++]) != ',')
303     {
304       *mem_addr_ptr = *mem_addr_ptr << 4;
305       *mem_addr_ptr |= fromhex (ch) & 0x0f;
306     }
307
308   for (j = 0; j < 4; j++)
309     {
310       if ((ch = from[i++]) == 0)
311         break;
312       *len_ptr = *len_ptr << 4;
313       *len_ptr |= fromhex (ch) & 0x0f;
314     }
315 }
316
317 void
318 decode_M_packet (from, mem_addr_ptr, len_ptr, to)
319      char *from, *to;
320      unsigned int *mem_addr_ptr, *len_ptr;
321 {
322   int i = 0, j = 0;
323   char ch;
324   *mem_addr_ptr = *len_ptr = 0;
325
326   while ((ch = from[i++]) != ',')
327     {
328       *mem_addr_ptr = *mem_addr_ptr << 4;
329       *mem_addr_ptr |= fromhex (ch) & 0x0f;
330     }
331
332   while ((ch = from[i++]) != ':')
333     {
334       *len_ptr = *len_ptr << 4;
335       *len_ptr |= fromhex (ch) & 0x0f;
336     }
337
338   convert_ascii_to_int (&from[i++], to, *len_ptr);
339 }
This page took 0.049747 seconds and 4 git commands to generate.