* gdbserver/{remote-gutils.c remote-server.c Makefile.in
[deliverable/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
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.043014 seconds and 5 git commands to generate.