]> Git Repo - binutils.git/blame - gdb/gdbserver/remote-utils.c
* gdbserver/{remote-gutils.c remote-server.c Makefile.in
[binutils.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>
28
29extern int remote_desc;
30extern int remote_debugging;
31extern int kiodebug;
32
33void remote_open ();
34void remote_send ();
35void putpkt ();
36void getpkt ();
37
38void write_ok ();
39void write_enn ();
40void convert_ascii_to_int ();
41void convert_int_to_ascii ();
42void prepare_resume_reply ();
43
44/* Open a connection to a remote debugger.
45 NAME is the filename used for communication. */
46
47void
48remote_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
70static int
71fromhex (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
84static int
85tohex (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
98void
99remote_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
112void
113putpkt (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
148static int
149readchar ()
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
159void
160getpkt (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
196void
197write_ok (buf)
198 char *buf;
199{
200 buf[0] = 'O';
201 buf[1] = 'k';
202 buf[2] = '\0';
203}
204
205void
206write_enn (buf)
207 char *buf;
208{
209 buf[0] = 'E';
210 buf[1] = 'N';
211 buf[2] = 'N';
212 buf[3] = '\0';
213}
214
215void
216convert_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
234void
235convert_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
248static char *
249outreg(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
265void
266prepare_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
293void
294decode_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
317void
318decode_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.054587 seconds and 4 git commands to generate.