]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbserver/remote-utils.c
* linux-low.c (fetch_register, usr_store_inferior_registers): Handle
[thirdparty/binutils-gdb.git] / gdb / gdbserver / remote-utils.c
CommitLineData
c906108c 1/* Remote utility routines for the remote server for GDB.
0a30fbc4 2 Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
a1928bad 3 2002, 2003, 2004, 2005
b6ba6518 4 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23#include "server.h"
24#include "terminal.h"
25#include <stdio.h>
26#include <string.h>
27#include <sys/ioctl.h>
28#include <sys/file.h>
29#include <netinet/in.h>
30#include <sys/socket.h>
31#include <netdb.h>
32#include <netinet/tcp.h>
33#include <sys/ioctl.h>
34#include <signal.h>
35#include <fcntl.h>
cf30a8e1
C
36#include <sys/time.h>
37#include <unistd.h>
0729219d 38#include <arpa/inet.h>
c906108c 39
f450004a
DJ
40#ifndef HAVE_SOCKLEN_T
41typedef int socklen_t;
42#endif
43
fd500816
DJ
44/* A cache entry for a successfully looked-up symbol. */
45struct sym_cache
46{
47 const char *name;
48 CORE_ADDR addr;
49 struct sym_cache *next;
50};
51
52/* The symbol cache. */
53static struct sym_cache *symbol_cache;
54
c906108c 55int remote_debug = 0;
03863182 56struct ui_file *gdb_stdlog;
c906108c
SS
57
58static int remote_desc;
59
0d62e5e8
DJ
60/* FIXME headerize? */
61extern int using_threads;
62extern int debug_threads;
63
c906108c
SS
64/* Open a connection to a remote debugger.
65 NAME is the filename used for communication. */
66
67void
fba45db2 68remote_open (char *name)
c906108c
SS
69{
70 int save_fcntl_flags;
e641a1ca 71
c906108c
SS
72 if (!strchr (name, ':'))
73 {
74 remote_desc = open (name, O_RDWR);
75 if (remote_desc < 0)
76 perror_with_name ("Could not open remote device");
77
78#ifdef HAVE_TERMIOS
79 {
80 struct termios termios;
c5aa993b 81 tcgetattr (remote_desc, &termios);
c906108c
SS
82
83 termios.c_iflag = 0;
84 termios.c_oflag = 0;
85 termios.c_lflag = 0;
c5aa993b 86 termios.c_cflag &= ~(CSIZE | PARENB);
c906108c 87 termios.c_cflag |= CLOCAL | CS8;
d0608e50 88 termios.c_cc[VMIN] = 1;
c906108c
SS
89 termios.c_cc[VTIME] = 0;
90
c5aa993b 91 tcsetattr (remote_desc, TCSANOW, &termios);
c906108c
SS
92 }
93#endif
94
95#ifdef HAVE_TERMIO
96 {
97 struct termio termio;
98 ioctl (remote_desc, TCGETA, &termio);
99
100 termio.c_iflag = 0;
101 termio.c_oflag = 0;
102 termio.c_lflag = 0;
c5aa993b 103 termio.c_cflag &= ~(CSIZE | PARENB);
c906108c 104 termio.c_cflag |= CLOCAL | CS8;
d0608e50 105 termio.c_cc[VMIN] = 1;
c906108c
SS
106 termio.c_cc[VTIME] = 0;
107
108 ioctl (remote_desc, TCSETA, &termio);
109 }
110#endif
111
112#ifdef HAVE_SGTTY
113 {
114 struct sgttyb sg;
115
116 ioctl (remote_desc, TIOCGETP, &sg);
117 sg.sg_flags = RAW;
118 ioctl (remote_desc, TIOCSETP, &sg);
119 }
120#endif
121
e641a1ca 122 fprintf (stderr, "Remote debugging using %s\n", name);
c906108c
SS
123 }
124 else
125 {
126 char *port_str;
127 int port;
128 struct sockaddr_in sockaddr;
f450004a 129 socklen_t tmp;
c906108c
SS
130 int tmp_desc;
131
132 port_str = strchr (name, ':');
133
134 port = atoi (port_str + 1);
135
136 tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
137 if (tmp_desc < 0)
138 perror_with_name ("Can't open socket");
139
140 /* Allow rapid reuse of this port. */
141 tmp = 1;
c5aa993b
JM
142 setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
143 sizeof (tmp));
c906108c
SS
144
145 sockaddr.sin_family = PF_INET;
c5aa993b 146 sockaddr.sin_port = htons (port);
c906108c
SS
147 sockaddr.sin_addr.s_addr = INADDR_ANY;
148
c5aa993b 149 if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
c906108c
SS
150 || listen (tmp_desc, 1))
151 perror_with_name ("Can't bind address");
152
6910d122
DJ
153 fprintf (stderr, "Listening on port %d\n", port);
154
c906108c 155 tmp = sizeof (sockaddr);
c5aa993b 156 remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
c906108c
SS
157 if (remote_desc == -1)
158 perror_with_name ("Accept failed");
159
c906108c
SS
160 /* Enable TCP keep alive process. */
161 tmp = 1;
c5aa993b 162 setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
c906108c
SS
163
164 /* Tell TCP not to delay small packets. This greatly speeds up
c5aa993b 165 interactive response. */
c906108c 166 tmp = 1;
373fe97f 167 setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
c5aa993b 168 (char *) &tmp, sizeof (tmp));
c906108c
SS
169
170 close (tmp_desc); /* No longer need this */
171
c5aa993b
JM
172 signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
173 exits when the remote side dies. */
e641a1ca
ML
174
175 /* Convert IP address to string. */
176 fprintf (stderr, "Remote debugging from host %s\n",
177 inet_ntoa (sockaddr.sin_addr));
c906108c
SS
178 }
179
180#if defined(F_SETFL) && defined (FASYNC)
181 save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
182 fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
cf30a8e1
C
183#if defined (F_SETOWN)
184 fcntl (remote_desc, F_SETOWN, getpid ());
94dfea5d 185#endif
cf30a8e1 186#endif
c906108c 187 disable_async_io ();
c906108c
SS
188}
189
190void
fba45db2 191remote_close (void)
c906108c
SS
192{
193 close (remote_desc);
194}
195
196/* Convert hex digit A to a number. */
197
198static int
fba45db2 199fromhex (int a)
c906108c
SS
200{
201 if (a >= '0' && a <= '9')
202 return a - '0';
203 else if (a >= 'a' && a <= 'f')
204 return a - 'a' + 10;
205 else
206 error ("Reply contains invalid hex digit");
0a30fbc4 207 return 0;
c906108c
SS
208}
209
ce3a066d
DJ
210int
211unhexify (char *bin, const char *hex, int count)
212{
213 int i;
214
215 for (i = 0; i < count; i++)
216 {
217 if (hex[0] == 0 || hex[1] == 0)
218 {
219 /* Hex string is short, or of uneven length.
220 Return the count that has been converted so far. */
221 return i;
222 }
223 *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
224 hex += 2;
225 }
226 return i;
227}
228
2f2893d9
DJ
229static void
230decode_address (CORE_ADDR *addrp, const char *start, int len)
231{
232 CORE_ADDR addr;
233 char ch;
234 int i;
235
236 addr = 0;
237 for (i = 0; i < len; i++)
238 {
239 ch = start[i];
240 addr = addr << 4;
241 addr = addr | (fromhex (ch) & 0x0f);
242 }
243 *addrp = addr;
244}
245
c906108c
SS
246/* Convert number NIB to a hex digit. */
247
248static int
fba45db2 249tohex (int nib)
c906108c
SS
250{
251 if (nib < 10)
252 return '0' + nib;
253 else
254 return 'a' + nib - 10;
255}
256
ce3a066d
DJ
257int
258hexify (char *hex, const char *bin, int count)
259{
260 int i;
261
262 /* May use a length, or a nul-terminated string as input. */
263 if (count == 0)
264 count = strlen (bin);
265
266 for (i = 0; i < count; i++)
267 {
268 *hex++ = tohex ((*bin >> 4) & 0xf);
269 *hex++ = tohex (*bin++ & 0xf);
270 }
271 *hex = 0;
272 return i;
273}
274
c906108c
SS
275/* Send a packet to the remote machine, with error checking.
276 The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */
277
278int
fba45db2 279putpkt (char *buf)
c906108c
SS
280{
281 int i;
282 unsigned char csum = 0;
0a30fbc4 283 char *buf2;
c906108c
SS
284 char buf3[1];
285 int cnt = strlen (buf);
286 char *p;
287
0a30fbc4
DJ
288 buf2 = malloc (PBUFSIZ);
289
c906108c
SS
290 /* Copy the packet into buffer BUF2, encapsulating it
291 and giving it a checksum. */
292
293 p = buf2;
294 *p++ = '$';
295
296 for (i = 0; i < cnt; i++)
297 {
298 csum += buf[i];
299 *p++ = buf[i];
300 }
301 *p++ = '#';
302 *p++ = tohex ((csum >> 4) & 0xf);
303 *p++ = tohex (csum & 0xf);
304
305 *p = '\0';
306
307 /* Send it over and over until we get a positive ack. */
308
309 do
310 {
311 int cc;
312
313 if (write (remote_desc, buf2, p - buf2) != p - buf2)
314 {
315 perror ("putpkt(write)");
316 return -1;
317 }
318
319 if (remote_debug)
0d62e5e8
DJ
320 {
321 fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
322 fflush (stderr);
323 }
c906108c
SS
324 cc = read (remote_desc, buf3, 1);
325 if (remote_debug)
0d62e5e8
DJ
326 {
327 fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
328 fflush (stderr);
329 }
330
c906108c
SS
331 if (cc <= 0)
332 {
333 if (cc == 0)
334 fprintf (stderr, "putpkt(read): Got EOF\n");
335 else
336 perror ("putpkt(read)");
337
0a30fbc4 338 free (buf2);
c906108c
SS
339 return -1;
340 }
0d62e5e8
DJ
341
342 /* Check for an input interrupt while we're here. */
343 if (buf3[0] == '\003')
e5379b03 344 (*the_target->send_signal) (SIGINT);
c906108c
SS
345 }
346 while (buf3[0] != '+');
347
0a30fbc4 348 free (buf2);
c906108c
SS
349 return 1; /* Success! */
350}
351
352/* Come here when we get an input interrupt from the remote side. This
353 interrupt should only be active while we are waiting for the child to do
354 something. About the only thing that should come through is a ^C, which
355 will cause us to send a SIGINT to the child. */
356
357static void
0a30fbc4 358input_interrupt (int unused)
c906108c 359{
cf30a8e1
C
360 fd_set readset;
361 struct timeval immediate = { 0, 0 };
c906108c 362
cf30a8e1
C
363 /* Protect against spurious interrupts. This has been observed to
364 be a problem under NetBSD 1.4 and 1.5. */
c906108c 365
cf30a8e1
C
366 FD_ZERO (&readset);
367 FD_SET (remote_desc, &readset);
368 if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
c906108c 369 {
cf30a8e1 370 int cc;
fd500816 371 char c = 0;
cf30a8e1
C
372
373 cc = read (remote_desc, &c, 1);
c906108c 374
cf30a8e1
C
375 if (cc != 1 || c != '\003')
376 {
fd500816
DJ
377 fprintf (stderr, "input_interrupt, count = %d c = %d ('%c')\n",
378 cc, c, c);
cf30a8e1
C
379 return;
380 }
381
e5379b03 382 (*the_target->send_signal) (SIGINT);
cf30a8e1 383 }
c906108c
SS
384}
385
62ea82f5
DJ
386void
387block_async_io (void)
388{
389 sigset_t sigio_set;
390 sigemptyset (&sigio_set);
391 sigaddset (&sigio_set, SIGIO);
392 sigprocmask (SIG_BLOCK, &sigio_set, NULL);
393}
394
395void
396unblock_async_io (void)
397{
398 sigset_t sigio_set;
399 sigemptyset (&sigio_set);
400 sigaddset (&sigio_set, SIGIO);
401 sigprocmask (SIG_UNBLOCK, &sigio_set, NULL);
402}
403
fd500816
DJ
404/* Asynchronous I/O support. SIGIO must be enabled when waiting, in order to
405 accept Control-C from the client, and must be disabled when talking to
406 the client. */
407
408/* Current state of asynchronous I/O. */
409static int async_io_enabled;
410
411/* Enable asynchronous I/O. */
c906108c 412void
fba45db2 413enable_async_io (void)
c906108c 414{
fd500816
DJ
415 if (async_io_enabled)
416 return;
417
c906108c 418 signal (SIGIO, input_interrupt);
fd500816 419 async_io_enabled = 1;
c906108c
SS
420}
421
fd500816 422/* Disable asynchronous I/O. */
c906108c 423void
fba45db2 424disable_async_io (void)
c906108c 425{
fd500816
DJ
426 if (!async_io_enabled)
427 return;
428
c906108c 429 signal (SIGIO, SIG_IGN);
fd500816 430 async_io_enabled = 0;
c906108c
SS
431}
432
433/* Returns next char from remote GDB. -1 if error. */
434
435static int
fba45db2 436readchar (void)
c906108c
SS
437{
438 static char buf[BUFSIZ];
439 static int bufcnt = 0;
440 static char *bufp;
441
442 if (bufcnt-- > 0)
443 return *bufp++ & 0x7f;
444
445 bufcnt = read (remote_desc, buf, sizeof (buf));
446
447 if (bufcnt <= 0)
448 {
449 if (bufcnt == 0)
450 fprintf (stderr, "readchar: Got EOF\n");
451 else
452 perror ("readchar");
453
454 return -1;
455 }
456
457 bufp = buf;
458 bufcnt--;
459 return *bufp++ & 0x7f;
460}
461
462/* Read a packet from the remote machine, with error checking,
463 and store it in BUF. Returns length of packet, or negative if error. */
464
465int
fba45db2 466getpkt (char *buf)
c906108c
SS
467{
468 char *bp;
469 unsigned char csum, c1, c2;
470 int c;
471
472 while (1)
473 {
474 csum = 0;
475
476 while (1)
477 {
478 c = readchar ();
479 if (c == '$')
480 break;
481 if (remote_debug)
0d62e5e8
DJ
482 {
483 fprintf (stderr, "[getpkt: discarding char '%c']\n", c);
484 fflush (stderr);
485 }
486
c906108c
SS
487 if (c < 0)
488 return -1;
489 }
490
491 bp = buf;
492 while (1)
493 {
494 c = readchar ();
495 if (c < 0)
496 return -1;
497 if (c == '#')
498 break;
499 *bp++ = c;
500 csum += c;
501 }
502 *bp = 0;
503
504 c1 = fromhex (readchar ());
505 c2 = fromhex (readchar ());
c5aa993b 506
c906108c
SS
507 if (csum == (c1 << 4) + c2)
508 break;
509
510 fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
511 (c1 << 4) + c2, csum, buf);
512 write (remote_desc, "-", 1);
513 }
514
515 if (remote_debug)
0d62e5e8
DJ
516 {
517 fprintf (stderr, "getpkt (\"%s\"); [sending ack] \n", buf);
518 fflush (stderr);
519 }
c906108c
SS
520
521 write (remote_desc, "+", 1);
522
523 if (remote_debug)
0d62e5e8
DJ
524 {
525 fprintf (stderr, "[sent ack]\n");
526 fflush (stderr);
527 }
528
c906108c
SS
529 return bp - buf;
530}
531
532void
fba45db2 533write_ok (char *buf)
c906108c
SS
534{
535 buf[0] = 'O';
536 buf[1] = 'K';
537 buf[2] = '\0';
538}
539
540void
fba45db2 541write_enn (char *buf)
c906108c 542{
c89dc5d4 543 /* Some day, we should define the meanings of the error codes... */
c906108c 544 buf[0] = 'E';
c89dc5d4
DJ
545 buf[1] = '0';
546 buf[2] = '1';
c906108c
SS
547 buf[3] = '\0';
548}
549
550void
f450004a 551convert_int_to_ascii (unsigned char *from, char *to, int n)
c906108c
SS
552{
553 int nib;
f450004a 554 int ch;
c906108c
SS
555 while (n--)
556 {
557 ch = *from++;
558 nib = ((ch & 0xf0) >> 4) & 0x0f;
559 *to++ = tohex (nib);
560 nib = ch & 0x0f;
561 *to++ = tohex (nib);
562 }
563 *to++ = 0;
564}
565
566
567void
f450004a 568convert_ascii_to_int (char *from, unsigned char *to, int n)
c906108c
SS
569{
570 int nib1, nib2;
571 while (n--)
572 {
573 nib1 = fromhex (*from++);
574 nib2 = fromhex (*from++);
575 *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
576 }
577}
578
579static char *
fba45db2 580outreg (int regno, char *buf)
c906108c 581{
5c44784c
JM
582 if ((regno >> 12) != 0)
583 *buf++ = tohex ((regno >> 12) & 0xf);
584 if ((regno >> 8) != 0)
585 *buf++ = tohex ((regno >> 8) & 0xf);
586 *buf++ = tohex ((regno >> 4) & 0xf);
c906108c
SS
587 *buf++ = tohex (regno & 0xf);
588 *buf++ = ':';
0d62e5e8
DJ
589 collect_register_as_string (regno, buf);
590 buf += 2 * register_size (regno);
c906108c
SS
591 *buf++ = ';';
592
593 return buf;
594}
595
0d62e5e8
DJ
596void
597new_thread_notify (int id)
598{
599 char own_buf[256];
600
601 /* The `n' response is not yet part of the remote protocol. Do nothing. */
602 if (1)
603 return;
604
605 if (server_waiting == 0)
606 return;
607
608 sprintf (own_buf, "n%x", id);
609 disable_async_io ();
610 putpkt (own_buf);
611 enable_async_io ();
612}
613
614void
615dead_thread_notify (int id)
616{
617 char own_buf[256];
618
619 /* The `x' response is not yet part of the remote protocol. Do nothing. */
620 if (1)
621 return;
622
623 sprintf (own_buf, "x%x", id);
624 disable_async_io ();
625 putpkt (own_buf);
626 enable_async_io ();
627}
628
c906108c 629void
fba45db2 630prepare_resume_reply (char *buf, char status, unsigned char signo)
c906108c 631{
0e98d0a7 632 int nib, sig;
c906108c
SS
633
634 *buf++ = status;
635
0e98d0a7
DJ
636 sig = (int)target_signal_from_host (signo);
637
638 nib = ((sig & 0xf0) >> 4);
c906108c 639 *buf++ = tohex (nib);
0e98d0a7 640 nib = sig & 0x0f;
c906108c
SS
641 *buf++ = tohex (nib);
642
643 if (status == 'T')
644 {
0a30fbc4 645 const char **regp = gdbserver_expedite_regs;
e013ee27
OF
646
647 if (the_target->stopped_by_watchpoint != NULL
648 && (*the_target->stopped_by_watchpoint) ())
649 {
650 CORE_ADDR addr;
651 int i;
652
653 strncpy (buf, "watch:", 6);
654 buf += 6;
655
656 addr = (*the_target->stopped_data_address) ();
657
658 /* Convert each byte of the address into two hexadecimal chars.
659 Note that we take sizeof (void *) instead of sizeof (addr);
660 this is to avoid sending a 64-bit address to a 32-bit GDB. */
661 for (i = sizeof (void *) * 2; i > 0; i--)
662 {
663 *buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
664 }
665 *buf++ = ';';
666 }
667
0a30fbc4 668 while (*regp)
5c44784c 669 {
0a30fbc4
DJ
670 buf = outreg (find_regno (*regp), buf);
671 regp ++;
5c44784c 672 }
c906108c 673
0d62e5e8
DJ
674 /* Formerly, if the debugger had not used any thread features we would not
675 burden it with a thread status response. This was for the benefit of
676 GDB 4.13 and older. However, in recent GDB versions the check
677 (``if (cont_thread != 0)'') does not have the desired effect because of
678 sillyness in the way that the remote protocol handles specifying a thread.
679 Since thread support relies on qSymbol support anyway, assume GDB can handle
680 threads. */
681
682 if (using_threads)
c906108c 683 {
0d62e5e8
DJ
684 /* FIXME right place to set this? */
685 thread_from_wait = ((struct inferior_list_entry *)current_inferior)->id;
686 if (debug_threads)
a1928bad 687 fprintf (stderr, "Writing resume reply for %ld\n\n", thread_from_wait);
89a208da
DJ
688 /* This if (1) ought to be unnecessary. But remote_wait in GDB
689 will claim this event belongs to inferior_ptid if we do not
690 specify a thread, and there's no way for gdbserver to know
691 what inferior_ptid is. */
692 if (1 || old_thread_from_wait != thread_from_wait)
c906108c 693 {
0d62e5e8 694 general_thread = thread_from_wait;
a1928bad 695 sprintf (buf, "thread:%lx;", thread_from_wait);
c906108c
SS
696 buf += strlen (buf);
697 old_thread_from_wait = thread_from_wait;
698 }
699 }
700 }
701 /* For W and X, we're done. */
702 *buf++ = 0;
703}
704
705void
fba45db2 706decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
c906108c
SS
707{
708 int i = 0, j = 0;
709 char ch;
710 *mem_addr_ptr = *len_ptr = 0;
711
712 while ((ch = from[i++]) != ',')
713 {
714 *mem_addr_ptr = *mem_addr_ptr << 4;
715 *mem_addr_ptr |= fromhex (ch) & 0x0f;
716 }
717
718 for (j = 0; j < 4; j++)
719 {
720 if ((ch = from[i++]) == 0)
721 break;
722 *len_ptr = *len_ptr << 4;
723 *len_ptr |= fromhex (ch) & 0x0f;
724 }
725}
726
727void
fba45db2 728decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
f450004a 729 unsigned char *to)
c906108c
SS
730{
731 int i = 0;
732 char ch;
733 *mem_addr_ptr = *len_ptr = 0;
734
735 while ((ch = from[i++]) != ',')
736 {
737 *mem_addr_ptr = *mem_addr_ptr << 4;
738 *mem_addr_ptr |= fromhex (ch) & 0x0f;
739 }
740
741 while ((ch = from[i++]) != ':')
742 {
743 *len_ptr = *len_ptr << 4;
744 *len_ptr |= fromhex (ch) & 0x0f;
745 }
746
747 convert_ascii_to_int (&from[i++], to, *len_ptr);
748}
2f2893d9 749
fd500816
DJ
750/* Ask GDB for the address of NAME, and return it in ADDRP if found.
751 Returns 1 if the symbol is found, 0 if it is not, -1 on error. */
752
2f2893d9
DJ
753int
754look_up_one_symbol (const char *name, CORE_ADDR *addrp)
755{
756 char own_buf[266], *p, *q;
757 int len;
fd500816
DJ
758 struct sym_cache *sym;
759
760 /* Check the cache first. */
761 for (sym = symbol_cache; sym; sym = sym->next)
762 if (strcmp (name, sym->name) == 0)
763 {
764 *addrp = sym->addr;
765 return 1;
766 }
2f2893d9
DJ
767
768 /* Send the request. */
769 strcpy (own_buf, "qSymbol:");
770 hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
771 if (putpkt (own_buf) < 0)
772 return -1;
773
774 /* FIXME: Eventually add buffer overflow checking (to getpkt?) */
775 len = getpkt (own_buf);
776 if (len < 0)
777 return -1;
778
779 if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
780 {
781 /* Malformed response. */
782 if (remote_debug)
0d62e5e8
DJ
783 {
784 fprintf (stderr, "Malformed response to qSymbol, ignoring.\n");
785 fflush (stderr);
786 }
787
2f2893d9
DJ
788 return -1;
789 }
790
791 p = own_buf + strlen ("qSymbol:");
792 q = p;
793 while (*q && *q != ':')
794 q++;
795
796 /* Make sure we found a value for the symbol. */
797 if (p == q || *q == '\0')
798 return 0;
799
800 decode_address (addrp, p, q - p);
fd500816
DJ
801
802 /* Save the symbol in our cache. */
803 sym = malloc (sizeof (*sym));
804 sym->name = strdup (name);
805 sym->addr = *addrp;
806 sym->next = symbol_cache;
807 symbol_cache = sym;
808
2f2893d9
DJ
809 return 1;
810}