]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbserver/remote-utils.c
* infrun.c (follow_fork): Initialize new step_* locals
[thirdparty/binutils-gdb.git] / gdb / gdbserver / remote-utils.c
CommitLineData
c906108c 1/* Remote utility routines for the remote server for GDB.
6aba47ca 2 Copyright (C) 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
0fb0cc75 3 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
9b254dd1 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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 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 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
20
21#include "server.h"
22#include "terminal.h"
5b1c542e 23#include "target.h"
c906108c
SS
24#include <stdio.h>
25#include <string.h>
b80864fb 26#if HAVE_SYS_IOCTL_H
c906108c 27#include <sys/ioctl.h>
b80864fb 28#endif
68070c10 29#if HAVE_SYS_FILE_H
c906108c 30#include <sys/file.h>
68070c10 31#endif
b80864fb 32#if HAVE_NETINET_IN_H
c906108c 33#include <netinet/in.h>
b80864fb
DJ
34#endif
35#if HAVE_SYS_SOCKET_H
c906108c 36#include <sys/socket.h>
b80864fb
DJ
37#endif
38#if HAVE_NETDB_H
c906108c 39#include <netdb.h>
b80864fb
DJ
40#endif
41#if HAVE_NETINET_TCP_H
c906108c 42#include <netinet/tcp.h>
b80864fb
DJ
43#endif
44#if HAVE_SYS_IOCTL_H
c906108c 45#include <sys/ioctl.h>
b80864fb 46#endif
68070c10 47#if HAVE_SIGNAL_H
c906108c 48#include <signal.h>
68070c10
PA
49#endif
50#if HAVE_FCNTL_H
c906108c 51#include <fcntl.h>
68070c10 52#endif
cf30a8e1 53#include <sys/time.h>
68070c10 54#if HAVE_UNISTD_H
cf30a8e1 55#include <unistd.h>
68070c10 56#endif
b80864fb 57#if HAVE_ARPA_INET_H
0729219d 58#include <arpa/inet.h>
b80864fb 59#endif
8264bb58 60#include <sys/stat.h>
68070c10 61#if HAVE_ERRNO_H
8264bb58 62#include <errno.h>
68070c10 63#endif
b80864fb
DJ
64
65#if USE_WIN32API
66#include <winsock.h>
67#endif
c906108c 68
f450004a
DJ
69#ifndef HAVE_SOCKLEN_T
70typedef int socklen_t;
71#endif
72
7390519e
PA
73#if USE_WIN32API
74# define INVALID_DESCRIPTOR INVALID_SOCKET
75#else
76# define INVALID_DESCRIPTOR -1
77#endif
78
fd500816
DJ
79/* A cache entry for a successfully looked-up symbol. */
80struct sym_cache
81{
95954743 82 char *name;
fd500816
DJ
83 CORE_ADDR addr;
84 struct sym_cache *next;
85};
86
c906108c 87int remote_debug = 0;
03863182 88struct ui_file *gdb_stdlog;
c906108c 89
7390519e 90static int remote_desc = INVALID_DESCRIPTOR;
c906108c 91
0d62e5e8
DJ
92/* FIXME headerize? */
93extern int using_threads;
94extern int debug_threads;
95
a6f3e723
SL
96/* If true, then GDB has requested noack mode. */
97int noack_mode = 0;
98/* If true, then we tell GDB to use noack mode by default. */
99int transport_is_reliable = 0;
100
0f48aa01 101#ifdef USE_WIN32API
68070c10
PA
102# define read(fd, buf, len) recv (fd, (char *) buf, len, 0)
103# define write(fd, buf, len) send (fd, (char *) buf, len, 0)
0f48aa01
DJ
104#endif
105
c906108c
SS
106/* Open a connection to a remote debugger.
107 NAME is the filename used for communication. */
108
109void
fba45db2 110remote_open (char *name)
c906108c 111{
b80864fb 112#if defined(F_SETFL) && defined (FASYNC)
c906108c 113 int save_fcntl_flags;
b80864fb 114#endif
8264bb58
DJ
115 char *port_str;
116
117 port_str = strchr (name, ':');
118 if (port_str == NULL)
c906108c 119 {
b80864fb
DJ
120#ifdef USE_WIN32API
121 error ("Only <host>:<port> is supported on this platform.");
122#else
8264bb58
DJ
123 struct stat statbuf;
124
125 if (stat (name, &statbuf) == 0
126 && (S_ISCHR (statbuf.st_mode) || S_ISFIFO (statbuf.st_mode)))
127 remote_desc = open (name, O_RDWR);
128 else
129 {
130 errno = EINVAL;
131 remote_desc = -1;
132 }
133
c906108c
SS
134 if (remote_desc < 0)
135 perror_with_name ("Could not open remote device");
136
137#ifdef HAVE_TERMIOS
138 {
139 struct termios termios;
c5aa993b 140 tcgetattr (remote_desc, &termios);
c906108c
SS
141
142 termios.c_iflag = 0;
143 termios.c_oflag = 0;
144 termios.c_lflag = 0;
c5aa993b 145 termios.c_cflag &= ~(CSIZE | PARENB);
c906108c 146 termios.c_cflag |= CLOCAL | CS8;
d0608e50 147 termios.c_cc[VMIN] = 1;
c906108c
SS
148 termios.c_cc[VTIME] = 0;
149
c5aa993b 150 tcsetattr (remote_desc, TCSANOW, &termios);
c906108c
SS
151 }
152#endif
153
154#ifdef HAVE_TERMIO
155 {
156 struct termio termio;
157 ioctl (remote_desc, TCGETA, &termio);
158
159 termio.c_iflag = 0;
160 termio.c_oflag = 0;
161 termio.c_lflag = 0;
c5aa993b 162 termio.c_cflag &= ~(CSIZE | PARENB);
c906108c 163 termio.c_cflag |= CLOCAL | CS8;
d0608e50 164 termio.c_cc[VMIN] = 1;
c906108c
SS
165 termio.c_cc[VTIME] = 0;
166
167 ioctl (remote_desc, TCSETA, &termio);
168 }
169#endif
170
171#ifdef HAVE_SGTTY
172 {
173 struct sgttyb sg;
174
175 ioctl (remote_desc, TIOCGETP, &sg);
176 sg.sg_flags = RAW;
177 ioctl (remote_desc, TIOCSETP, &sg);
178 }
179#endif
180
e641a1ca 181 fprintf (stderr, "Remote debugging using %s\n", name);
b80864fb 182#endif /* USE_WIN32API */
a6f3e723
SL
183
184 transport_is_reliable = 0;
c906108c
SS
185 }
186 else
187 {
b80864fb
DJ
188#ifdef USE_WIN32API
189 static int winsock_initialized;
190#endif
c906108c
SS
191 int port;
192 struct sockaddr_in sockaddr;
f450004a 193 socklen_t tmp;
c906108c 194 int tmp_desc;
2d717e4f 195 char *port_end;
c906108c 196
2d717e4f
DJ
197 port = strtoul (port_str + 1, &port_end, 10);
198 if (port_str[1] == '\0' || *port_end != '\0')
199 fatal ("Bad port argument: %s", name);
c906108c 200
b80864fb
DJ
201#ifdef USE_WIN32API
202 if (!winsock_initialized)
203 {
204 WSADATA wsad;
205
206 WSAStartup (MAKEWORD (1, 0), &wsad);
207 winsock_initialized = 1;
208 }
209#endif
210
211 tmp_desc = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
c906108c
SS
212 if (tmp_desc < 0)
213 perror_with_name ("Can't open socket");
214
215 /* Allow rapid reuse of this port. */
216 tmp = 1;
c5aa993b
JM
217 setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp,
218 sizeof (tmp));
c906108c
SS
219
220 sockaddr.sin_family = PF_INET;
c5aa993b 221 sockaddr.sin_port = htons (port);
c906108c
SS
222 sockaddr.sin_addr.s_addr = INADDR_ANY;
223
c5aa993b 224 if (bind (tmp_desc, (struct sockaddr *) &sockaddr, sizeof (sockaddr))
c906108c
SS
225 || listen (tmp_desc, 1))
226 perror_with_name ("Can't bind address");
227
6f8486da
DJ
228 /* If port is zero, a random port will be selected, and the
229 fprintf below needs to know what port was selected. */
230 if (port == 0)
231 {
232 socklen_t len = sizeof (sockaddr);
233 if (getsockname (tmp_desc, (struct sockaddr *) &sockaddr, &len) < 0
234 || len < sizeof (sockaddr))
235 perror_with_name ("Can't determine port");
236 port = ntohs (sockaddr.sin_port);
237 }
238
6910d122 239 fprintf (stderr, "Listening on port %d\n", port);
b80864fb 240 fflush (stderr);
6910d122 241
c906108c 242 tmp = sizeof (sockaddr);
c5aa993b 243 remote_desc = accept (tmp_desc, (struct sockaddr *) &sockaddr, &tmp);
c906108c
SS
244 if (remote_desc == -1)
245 perror_with_name ("Accept failed");
246
c906108c
SS
247 /* Enable TCP keep alive process. */
248 tmp = 1;
aa0403d9
PA
249 setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE,
250 (char *) &tmp, sizeof (tmp));
c906108c
SS
251
252 /* Tell TCP not to delay small packets. This greatly speeds up
1b3f6016 253 interactive response. */
c906108c 254 tmp = 1;
373fe97f 255 setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
c5aa993b 256 (char *) &tmp, sizeof (tmp));
c906108c 257
b80864fb
DJ
258
259#ifndef USE_WIN32API
c906108c
SS
260 close (tmp_desc); /* No longer need this */
261
c5aa993b
JM
262 signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
263 exits when the remote side dies. */
b80864fb
DJ
264#else
265 closesocket (tmp_desc); /* No longer need this */
266#endif
e641a1ca
ML
267
268 /* Convert IP address to string. */
1b3f6016
PA
269 fprintf (stderr, "Remote debugging from host %s\n",
270 inet_ntoa (sockaddr.sin_addr));
a6f3e723
SL
271
272 transport_is_reliable = 1;
c906108c
SS
273 }
274
275#if defined(F_SETFL) && defined (FASYNC)
276 save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
277 fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
cf30a8e1
C
278#if defined (F_SETOWN)
279 fcntl (remote_desc, F_SETOWN, getpid ());
94dfea5d 280#endif
cf30a8e1 281#endif
bd99dc85
PA
282
283 /* Register the event loop handler. */
284 add_file_handler (remote_desc, handle_serial_event, NULL);
c906108c
SS
285}
286
287void
fba45db2 288remote_close (void)
c906108c 289{
bd99dc85
PA
290 delete_file_handler (remote_desc);
291
b80864fb
DJ
292#ifdef USE_WIN32API
293 closesocket (remote_desc);
294#else
c906108c 295 close (remote_desc);
b80864fb 296#endif
c906108c
SS
297}
298
299/* Convert hex digit A to a number. */
300
301static int
fba45db2 302fromhex (int a)
c906108c
SS
303{
304 if (a >= '0' && a <= '9')
305 return a - '0';
306 else if (a >= 'a' && a <= 'f')
307 return a - 'a' + 10;
308 else
309 error ("Reply contains invalid hex digit");
0a30fbc4 310 return 0;
c906108c
SS
311}
312
95954743
PA
313static const char hexchars[] = "0123456789abcdef";
314
315static int
316ishex (int ch, int *val)
317{
318 if ((ch >= 'a') && (ch <= 'f'))
319 {
320 *val = ch - 'a' + 10;
321 return 1;
322 }
323 if ((ch >= 'A') && (ch <= 'F'))
324 {
325 *val = ch - 'A' + 10;
326 return 1;
327 }
328 if ((ch >= '0') && (ch <= '9'))
329 {
330 *val = ch - '0';
331 return 1;
332 }
333 return 0;
334}
335
ce3a066d
DJ
336int
337unhexify (char *bin, const char *hex, int count)
338{
339 int i;
340
341 for (i = 0; i < count; i++)
342 {
343 if (hex[0] == 0 || hex[1] == 0)
1b3f6016
PA
344 {
345 /* Hex string is short, or of uneven length.
346 Return the count that has been converted so far. */
347 return i;
348 }
ce3a066d
DJ
349 *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
350 hex += 2;
351 }
352 return i;
353}
354
dae5f5cf 355void
2f2893d9
DJ
356decode_address (CORE_ADDR *addrp, const char *start, int len)
357{
358 CORE_ADDR addr;
359 char ch;
360 int i;
361
362 addr = 0;
363 for (i = 0; i < len; i++)
364 {
365 ch = start[i];
366 addr = addr << 4;
367 addr = addr | (fromhex (ch) & 0x0f);
368 }
369 *addrp = addr;
370}
371
89be2091
DJ
372const char *
373decode_address_to_semicolon (CORE_ADDR *addrp, const char *start)
374{
375 const char *end;
376
377 end = start;
378 while (*end != '\0' && *end != ';')
379 end++;
380
381 decode_address (addrp, start, end - start);
382
383 if (*end == ';')
384 end++;
385 return end;
386}
387
c906108c
SS
388/* Convert number NIB to a hex digit. */
389
390static int
fba45db2 391tohex (int nib)
c906108c
SS
392{
393 if (nib < 10)
394 return '0' + nib;
395 else
396 return 'a' + nib - 10;
397}
398
ce3a066d
DJ
399int
400hexify (char *hex, const char *bin, int count)
401{
402 int i;
403
404 /* May use a length, or a nul-terminated string as input. */
405 if (count == 0)
406 count = strlen (bin);
407
408 for (i = 0; i < count; i++)
409 {
410 *hex++ = tohex ((*bin >> 4) & 0xf);
411 *hex++ = tohex (*bin++ & 0xf);
412 }
413 *hex = 0;
414 return i;
415}
416
01f9e8fa
DJ
417/* Convert BUFFER, binary data at least LEN bytes long, into escaped
418 binary data in OUT_BUF. Set *OUT_LEN to the length of the data
419 encoded in OUT_BUF, and return the number of bytes in OUT_BUF
420 (which may be more than *OUT_LEN due to escape characters). The
421 total number of bytes in the output buffer will be at most
422 OUT_MAXLEN. */
423
424int
425remote_escape_output (const gdb_byte *buffer, int len,
426 gdb_byte *out_buf, int *out_len,
427 int out_maxlen)
428{
429 int input_index, output_index;
430
431 output_index = 0;
432 for (input_index = 0; input_index < len; input_index++)
433 {
434 gdb_byte b = buffer[input_index];
435
436 if (b == '$' || b == '#' || b == '}' || b == '*')
437 {
438 /* These must be escaped. */
439 if (output_index + 2 > out_maxlen)
440 break;
441 out_buf[output_index++] = '}';
442 out_buf[output_index++] = b ^ 0x20;
443 }
444 else
445 {
446 if (output_index + 1 > out_maxlen)
447 break;
448 out_buf[output_index++] = b;
449 }
450 }
451
452 *out_len = input_index;
453 return output_index;
454}
455
456/* Convert BUFFER, escaped data LEN bytes long, into binary data
457 in OUT_BUF. Return the number of bytes written to OUT_BUF.
458 Raise an error if the total number of bytes exceeds OUT_MAXLEN.
459
460 This function reverses remote_escape_output. It allows more
461 escaped characters than that function does, in particular because
462 '*' must be escaped to avoid the run-length encoding processing
463 in reading packets. */
464
465static int
466remote_unescape_input (const gdb_byte *buffer, int len,
467 gdb_byte *out_buf, int out_maxlen)
468{
469 int input_index, output_index;
470 int escaped;
471
472 output_index = 0;
473 escaped = 0;
474 for (input_index = 0; input_index < len; input_index++)
475 {
476 gdb_byte b = buffer[input_index];
477
478 if (output_index + 1 > out_maxlen)
479 error ("Received too much data from the target.");
480
481 if (escaped)
482 {
483 out_buf[output_index++] = b ^ 0x20;
484 escaped = 0;
485 }
486 else if (b == '}')
487 escaped = 1;
488 else
489 out_buf[output_index++] = b;
490 }
491
492 if (escaped)
493 error ("Unmatched escape character in target response.");
494
495 return output_index;
496}
497
5ffff7c1
DJ
498/* Look for a sequence of characters which can be run-length encoded.
499 If there are any, update *CSUM and *P. Otherwise, output the
500 single character. Return the number of characters consumed. */
501
502static int
503try_rle (char *buf, int remaining, unsigned char *csum, char **p)
504{
505 int n;
506
507 /* Always output the character. */
508 *csum += buf[0];
509 *(*p)++ = buf[0];
510
511 /* Don't go past '~'. */
512 if (remaining > 97)
513 remaining = 97;
514
515 for (n = 1; n < remaining; n++)
516 if (buf[n] != buf[0])
517 break;
518
519 /* N is the index of the first character not the same as buf[0].
520 buf[0] is counted twice, so by decrementing N, we get the number
521 of characters the RLE sequence will replace. */
522 n--;
523
524 if (n < 3)
525 return 1;
526
527 /* Skip the frame characters. The manual says to skip '+' and '-'
528 also, but there's no reason to. Unfortunately these two unusable
529 characters double the encoded length of a four byte zero
530 value. */
531 while (n + 29 == '$' || n + 29 == '#')
532 n--;
533
534 *csum += '*';
535 *(*p)++ = '*';
536 *csum += n + 29;
537 *(*p)++ = n + 29;
538
539 return n + 1;
540}
541
95954743
PA
542char *
543unpack_varlen_hex (char *buff, /* packet to parse */
544 ULONGEST *result)
545{
546 int nibble;
547 ULONGEST retval = 0;
548
549 while (ishex (*buff, &nibble))
550 {
551 buff++;
552 retval = retval << 4;
553 retval |= nibble & 0x0f;
554 }
555 *result = retval;
556 return buff;
557}
558
559/* Write a PTID to BUF. Returns BUF+CHARACTERS_WRITTEN. */
560
561char *
562write_ptid (char *buf, ptid_t ptid)
563{
564 int pid, tid;
565
566 if (multi_process)
567 {
568 pid = ptid_get_pid (ptid);
569 if (pid < 0)
570 buf += sprintf (buf, "p-%x.", -pid);
571 else
572 buf += sprintf (buf, "p%x.", pid);
573 }
574 tid = ptid_get_lwp (ptid);
575 if (tid < 0)
576 buf += sprintf (buf, "-%x", -tid);
577 else
578 buf += sprintf (buf, "%x", tid);
579
580 return buf;
581}
582
583ULONGEST
584hex_or_minus_one (char *buf, char **obuf)
585{
586 ULONGEST ret;
587
588 if (strncmp (buf, "-1", 2) == 0)
589 {
590 ret = (ULONGEST) -1;
591 buf += 2;
592 }
593 else
594 buf = unpack_varlen_hex (buf, &ret);
595
596 if (obuf)
597 *obuf = buf;
598
599 return ret;
600}
601
602/* Extract a PTID from BUF. If non-null, OBUF is set to the to one
603 passed the last parsed char. Returns null_ptid on error. */
604ptid_t
605read_ptid (char *buf, char **obuf)
606{
607 char *p = buf;
608 char *pp;
609 ULONGEST pid = 0, tid = 0;
610
611 if (*p == 'p')
612 {
613 /* Multi-process ptid. */
614 pp = unpack_varlen_hex (p + 1, &pid);
615 if (*pp != '.')
616 error ("invalid remote ptid: %s\n", p);
617
618 p = pp + 1;
619
620 tid = hex_or_minus_one (p, &pp);
621
622 if (obuf)
623 *obuf = pp;
624 return ptid_build (pid, tid, 0);
625 }
626
627 /* No multi-process. Just a tid. */
628 tid = hex_or_minus_one (p, &pp);
629
630 /* Since the stub is not sending a process id, then default to
631 what's in the current inferior. */
632 pid = ptid_get_pid (((struct inferior_list_entry *) current_inferior)->id);
633
634 if (obuf)
635 *obuf = pp;
636 return ptid_build (pid, tid, 0);
637}
638
c906108c 639/* Send a packet to the remote machine, with error checking.
01f9e8fa
DJ
640 The data of the packet is in BUF, and the length of the
641 packet is in CNT. Returns >= 0 on success, -1 otherwise. */
c906108c 642
bd99dc85
PA
643static int
644putpkt_binary_1 (char *buf, int cnt, int is_notif)
c906108c
SS
645{
646 int i;
647 unsigned char csum = 0;
0a30fbc4 648 char *buf2;
c906108c 649 char buf3[1];
c906108c
SS
650 char *p;
651
bca929d3 652 buf2 = xmalloc (PBUFSIZ);
0a30fbc4 653
c906108c
SS
654 /* Copy the packet into buffer BUF2, encapsulating it
655 and giving it a checksum. */
656
657 p = buf2;
bd99dc85
PA
658 if (is_notif)
659 *p++ = '%';
660 else
661 *p++ = '$';
c906108c 662
5ffff7c1
DJ
663 for (i = 0; i < cnt;)
664 i += try_rle (buf + i, cnt - i, &csum, &p);
665
c906108c
SS
666 *p++ = '#';
667 *p++ = tohex ((csum >> 4) & 0xf);
668 *p++ = tohex (csum & 0xf);
669
670 *p = '\0';
671
672 /* Send it over and over until we get a positive ack. */
673
674 do
675 {
676 int cc;
677
0f48aa01 678 if (write (remote_desc, buf2, p - buf2) != p - buf2)
c906108c
SS
679 {
680 perror ("putpkt(write)");
f88c79e6 681 free (buf2);
c906108c
SS
682 return -1;
683 }
684
bd99dc85 685 if (noack_mode || is_notif)
a6f3e723
SL
686 {
687 /* Don't expect an ack then. */
688 if (remote_debug)
689 {
bd99dc85
PA
690 if (is_notif)
691 fprintf (stderr, "putpkt (\"%s\"); [notif]\n", buf2);
692 else
693 fprintf (stderr, "putpkt (\"%s\"); [noack mode]\n", buf2);
a6f3e723
SL
694 fflush (stderr);
695 }
696 break;
697 }
698
c906108c 699 if (remote_debug)
0d62e5e8
DJ
700 {
701 fprintf (stderr, "putpkt (\"%s\"); [looking for ack]\n", buf2);
702 fflush (stderr);
703 }
0f48aa01 704 cc = read (remote_desc, buf3, 1);
c906108c 705 if (remote_debug)
0d62e5e8
DJ
706 {
707 fprintf (stderr, "[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
708 fflush (stderr);
709 }
710
c906108c
SS
711 if (cc <= 0)
712 {
713 if (cc == 0)
714 fprintf (stderr, "putpkt(read): Got EOF\n");
715 else
716 perror ("putpkt(read)");
717
0a30fbc4 718 free (buf2);
c906108c
SS
719 return -1;
720 }
0d62e5e8
DJ
721
722 /* Check for an input interrupt while we're here. */
2d717e4f 723 if (buf3[0] == '\003' && current_inferior != NULL)
ef57601b 724 (*the_target->request_interrupt) ();
c906108c
SS
725 }
726 while (buf3[0] != '+');
727
0a30fbc4 728 free (buf2);
c906108c
SS
729 return 1; /* Success! */
730}
731
bd99dc85
PA
732int
733putpkt_binary (char *buf, int cnt)
734{
735 return putpkt_binary_1 (buf, cnt, 0);
736}
737
01f9e8fa
DJ
738/* Send a packet to the remote machine, with error checking. The data
739 of the packet is in BUF, and the packet should be a NUL-terminated
740 string. Returns >= 0 on success, -1 otherwise. */
741
742int
743putpkt (char *buf)
744{
745 return putpkt_binary (buf, strlen (buf));
746}
747
bd99dc85
PA
748int
749putpkt_notif (char *buf)
750{
751 return putpkt_binary_1 (buf, strlen (buf), 1);
752}
753
c906108c
SS
754/* Come here when we get an input interrupt from the remote side. This
755 interrupt should only be active while we are waiting for the child to do
756 something. About the only thing that should come through is a ^C, which
ef57601b 757 will cause us to request child interruption. */
c906108c
SS
758
759static void
0a30fbc4 760input_interrupt (int unused)
c906108c 761{
cf30a8e1
C
762 fd_set readset;
763 struct timeval immediate = { 0, 0 };
c906108c 764
cf30a8e1
C
765 /* Protect against spurious interrupts. This has been observed to
766 be a problem under NetBSD 1.4 and 1.5. */
c906108c 767
cf30a8e1
C
768 FD_ZERO (&readset);
769 FD_SET (remote_desc, &readset);
770 if (select (remote_desc + 1, &readset, 0, 0, &immediate) > 0)
c906108c 771 {
cf30a8e1 772 int cc;
fd500816 773 char c = 0;
7390519e 774
0f48aa01 775 cc = read (remote_desc, &c, 1);
c906108c 776
2d717e4f 777 if (cc != 1 || c != '\003' || current_inferior == NULL)
cf30a8e1 778 {
fd500816
DJ
779 fprintf (stderr, "input_interrupt, count = %d c = %d ('%c')\n",
780 cc, c, c);
cf30a8e1
C
781 return;
782 }
7390519e 783
ef57601b 784 (*the_target->request_interrupt) ();
cf30a8e1 785 }
c906108c 786}
7390519e
PA
787
788/* Check if the remote side sent us an interrupt request (^C). */
789void
790check_remote_input_interrupt_request (void)
791{
792 /* This function may be called before establishing communications,
793 therefore we need to validate the remote descriptor. */
794
795 if (remote_desc == INVALID_DESCRIPTOR)
796 return;
797
798 input_interrupt (0);
799}
b80864fb
DJ
800
801/* Asynchronous I/O support. SIGIO must be enabled when waiting, in order to
802 accept Control-C from the client, and must be disabled when talking to
803 the client. */
c906108c 804
a20d5e98 805static void
62ea82f5
DJ
806unblock_async_io (void)
807{
b80864fb 808#ifndef USE_WIN32API
62ea82f5 809 sigset_t sigio_set;
a20d5e98 810
62ea82f5
DJ
811 sigemptyset (&sigio_set);
812 sigaddset (&sigio_set, SIGIO);
813 sigprocmask (SIG_UNBLOCK, &sigio_set, NULL);
b80864fb 814#endif
62ea82f5
DJ
815}
816
fd500816
DJ
817/* Current state of asynchronous I/O. */
818static int async_io_enabled;
819
820/* Enable asynchronous I/O. */
c906108c 821void
fba45db2 822enable_async_io (void)
c906108c 823{
fd500816
DJ
824 if (async_io_enabled)
825 return;
826
b80864fb 827#ifndef USE_WIN32API
c906108c 828 signal (SIGIO, input_interrupt);
b80864fb 829#endif
fd500816 830 async_io_enabled = 1;
c906108c
SS
831}
832
fd500816 833/* Disable asynchronous I/O. */
c906108c 834void
fba45db2 835disable_async_io (void)
c906108c 836{
fd500816
DJ
837 if (!async_io_enabled)
838 return;
839
b80864fb 840#ifndef USE_WIN32API
c906108c 841 signal (SIGIO, SIG_IGN);
b80864fb 842#endif
fd500816 843 async_io_enabled = 0;
c906108c
SS
844}
845
a20d5e98
DJ
846void
847initialize_async_io (void)
848{
849 /* Make sure that async I/O starts disabled. */
850 async_io_enabled = 1;
851 disable_async_io ();
852
853 /* Make sure the signal is unblocked. */
854 unblock_async_io ();
855}
856
c906108c
SS
857/* Returns next char from remote GDB. -1 if error. */
858
859static int
fba45db2 860readchar (void)
c906108c 861{
01f9e8fa 862 static unsigned char buf[BUFSIZ];
c906108c 863 static int bufcnt = 0;
01f9e8fa 864 static unsigned char *bufp;
c906108c
SS
865
866 if (bufcnt-- > 0)
01f9e8fa 867 return *bufp++;
c906108c 868
0f48aa01 869 bufcnt = read (remote_desc, buf, sizeof (buf));
c906108c
SS
870
871 if (bufcnt <= 0)
872 {
873 if (bufcnt == 0)
874 fprintf (stderr, "readchar: Got EOF\n");
875 else
876 perror ("readchar");
877
878 return -1;
879 }
880
881 bufp = buf;
882 bufcnt--;
b79d787e 883 return *bufp++;
c906108c
SS
884}
885
886/* Read a packet from the remote machine, with error checking,
887 and store it in BUF. Returns length of packet, or negative if error. */
888
889int
fba45db2 890getpkt (char *buf)
c906108c
SS
891{
892 char *bp;
893 unsigned char csum, c1, c2;
894 int c;
895
896 while (1)
897 {
898 csum = 0;
899
900 while (1)
901 {
902 c = readchar ();
903 if (c == '$')
904 break;
905 if (remote_debug)
0d62e5e8
DJ
906 {
907 fprintf (stderr, "[getpkt: discarding char '%c']\n", c);
908 fflush (stderr);
909 }
910
c906108c
SS
911 if (c < 0)
912 return -1;
913 }
914
915 bp = buf;
916 while (1)
917 {
918 c = readchar ();
919 if (c < 0)
920 return -1;
921 if (c == '#')
922 break;
923 *bp++ = c;
924 csum += c;
925 }
926 *bp = 0;
927
928 c1 = fromhex (readchar ());
929 c2 = fromhex (readchar ());
c5aa993b 930
c906108c
SS
931 if (csum == (c1 << 4) + c2)
932 break;
933
a6f3e723
SL
934 if (noack_mode)
935 {
936 fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s [no-ack-mode, Bad medium?]\n",
937 (c1 << 4) + c2, csum, buf);
938 /* Not much we can do, GDB wasn't expecting an ack/nac. */
939 break;
940 }
941
c906108c
SS
942 fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
943 (c1 << 4) + c2, csum, buf);
0f48aa01 944 write (remote_desc, "-", 1);
c906108c
SS
945 }
946
a6f3e723 947 if (!noack_mode)
0d62e5e8 948 {
a6f3e723
SL
949 if (remote_debug)
950 {
951 fprintf (stderr, "getpkt (\"%s\"); [sending ack] \n", buf);
952 fflush (stderr);
953 }
c906108c 954
a6f3e723 955 write (remote_desc, "+", 1);
c906108c 956
a6f3e723
SL
957 if (remote_debug)
958 {
959 fprintf (stderr, "[sent ack]\n");
960 fflush (stderr);
961 }
0d62e5e8 962 }
86b1f9c5
PM
963 else
964 {
965 if (remote_debug)
966 {
967 fprintf (stderr, "getpkt (\"%s\"); [no ack sent] \n", buf);
968 fflush (stderr);
969 }
970 }
0d62e5e8 971
c906108c
SS
972 return bp - buf;
973}
974
975void
fba45db2 976write_ok (char *buf)
c906108c
SS
977{
978 buf[0] = 'O';
979 buf[1] = 'K';
980 buf[2] = '\0';
981}
982
983void
fba45db2 984write_enn (char *buf)
c906108c 985{
c89dc5d4 986 /* Some day, we should define the meanings of the error codes... */
c906108c 987 buf[0] = 'E';
c89dc5d4
DJ
988 buf[1] = '0';
989 buf[2] = '1';
c906108c
SS
990 buf[3] = '\0';
991}
992
993void
f450004a 994convert_int_to_ascii (unsigned char *from, char *to, int n)
c906108c
SS
995{
996 int nib;
f450004a 997 int ch;
c906108c
SS
998 while (n--)
999 {
1000 ch = *from++;
1001 nib = ((ch & 0xf0) >> 4) & 0x0f;
1002 *to++ = tohex (nib);
1003 nib = ch & 0x0f;
1004 *to++ = tohex (nib);
1005 }
1006 *to++ = 0;
1007}
1008
1009
1010void
f450004a 1011convert_ascii_to_int (char *from, unsigned char *to, int n)
c906108c
SS
1012{
1013 int nib1, nib2;
1014 while (n--)
1015 {
1016 nib1 = fromhex (*from++);
1017 nib2 = fromhex (*from++);
1018 *to++ = (((nib1 & 0x0f) << 4) & 0xf0) | (nib2 & 0x0f);
1019 }
1020}
1021
1022static char *
fba45db2 1023outreg (int regno, char *buf)
c906108c 1024{
5c44784c
JM
1025 if ((regno >> 12) != 0)
1026 *buf++ = tohex ((regno >> 12) & 0xf);
1027 if ((regno >> 8) != 0)
1028 *buf++ = tohex ((regno >> 8) & 0xf);
1029 *buf++ = tohex ((regno >> 4) & 0xf);
c906108c
SS
1030 *buf++ = tohex (regno & 0xf);
1031 *buf++ = ':';
0d62e5e8
DJ
1032 collect_register_as_string (regno, buf);
1033 buf += 2 * register_size (regno);
c906108c
SS
1034 *buf++ = ';';
1035
1036 return buf;
1037}
1038
0d62e5e8
DJ
1039void
1040new_thread_notify (int id)
1041{
1042 char own_buf[256];
1043
1044 /* The `n' response is not yet part of the remote protocol. Do nothing. */
1045 if (1)
1046 return;
1047
1048 if (server_waiting == 0)
1049 return;
1050
1051 sprintf (own_buf, "n%x", id);
1052 disable_async_io ();
1053 putpkt (own_buf);
1054 enable_async_io ();
1055}
1056
1057void
1058dead_thread_notify (int id)
1059{
1060 char own_buf[256];
1061
1062 /* The `x' response is not yet part of the remote protocol. Do nothing. */
1063 if (1)
1064 return;
1065
1066 sprintf (own_buf, "x%x", id);
1067 disable_async_io ();
1068 putpkt (own_buf);
1069 enable_async_io ();
1070}
1071
c906108c 1072void
95954743 1073prepare_resume_reply (char *buf, ptid_t ptid,
5b1c542e 1074 struct target_waitstatus *status)
c906108c 1075{
5b1c542e 1076 if (debug_threads)
95954743
PA
1077 fprintf (stderr, "Writing resume reply for %s:%d\n\n",
1078 target_pid_to_str (ptid), status->kind);
c906108c 1079
5b1c542e 1080 switch (status->kind)
c906108c 1081 {
5b1c542e
PA
1082 case TARGET_WAITKIND_STOPPED:
1083 {
1084 struct thread_info *saved_inferior;
1085 const char **regp;
e013ee27 1086
5b1c542e
PA
1087 sprintf (buf, "T%02x", status->value.sig);
1088 buf += strlen (buf);
e013ee27 1089
5b1c542e 1090 regp = gdbserver_expedite_regs;
e013ee27 1091
5b1c542e 1092 saved_inferior = current_inferior;
e013ee27 1093
95954743 1094 current_inferior = find_thread_pid (ptid);
e013ee27 1095
5b1c542e
PA
1096 if (the_target->stopped_by_watchpoint != NULL
1097 && (*the_target->stopped_by_watchpoint) ())
1098 {
1099 CORE_ADDR addr;
1100 int i;
c906108c 1101
5b1c542e
PA
1102 strncpy (buf, "watch:", 6);
1103 buf += 6;
0d62e5e8 1104
5b1c542e 1105 addr = (*the_target->stopped_data_address) ();
255e7678 1106
5b1c542e
PA
1107 /* Convert each byte of the address into two hexadecimal
1108 chars. Note that we take sizeof (void *) instead of
1109 sizeof (addr); this is to avoid sending a 64-bit
1110 address to a 32-bit GDB. */
1111 for (i = sizeof (void *) * 2; i > 0; i--)
1112 *buf++ = tohex ((addr >> (i - 1) * 4) & 0xf);
1113 *buf++ = ';';
1114 }
1115
1116 while (*regp)
1117 {
1118 buf = outreg (find_regno (*regp), buf);
1119 regp ++;
1120 }
5472f405 1121 *buf = '\0';
5b1c542e
PA
1122
1123 /* Formerly, if the debugger had not used any thread features
1124 we would not burden it with a thread status response. This
1125 was for the benefit of GDB 4.13 and older. However, in
1126 recent GDB versions the check (``if (cont_thread != 0)'')
1127 does not have the desired effect because of sillyness in
1128 the way that the remote protocol handles specifying a
1129 thread. Since thread support relies on qSymbol support
1130 anyway, assume GDB can handle threads. */
1131
1132 if (using_threads && !disable_packet_Tthread)
1133 {
1134 /* This if (1) ought to be unnecessary. But remote_wait
1135 in GDB will claim this event belongs to inferior_ptid
1136 if we do not specify a thread, and there's no way for
1137 gdbserver to know what inferior_ptid is. */
95954743 1138 if (1 || !ptid_equal (general_thread, ptid))
5b1c542e 1139 {
bd99dc85
PA
1140 /* In non-stop, don't change the general thread behind
1141 GDB's back. */
1142 if (!non_stop)
1143 general_thread = ptid;
95954743
PA
1144 sprintf (buf, "thread:");
1145 buf += strlen (buf);
1146 buf = write_ptid (buf, ptid);
1147 strcat (buf, ";");
5b1c542e
PA
1148 buf += strlen (buf);
1149 }
1150 }
1151
1152 if (dlls_changed)
1153 {
1154 strcpy (buf, "library:;");
1155 buf += strlen (buf);
1156 dlls_changed = 0;
1157 }
1158
1159 current_inferior = saved_inferior;
1160 }
1161 break;
1162 case TARGET_WAITKIND_EXITED:
95954743
PA
1163 if (multi_process)
1164 sprintf (buf, "W%x;process:%x",
1165 status->value.integer, ptid_get_pid (ptid));
1166 else
1167 sprintf (buf, "W%02x", status->value.integer);
5b1c542e
PA
1168 break;
1169 case TARGET_WAITKIND_SIGNALLED:
95954743
PA
1170 if (multi_process)
1171 sprintf (buf, "X%x;process:%x",
1172 status->value.sig, ptid_get_pid (ptid));
1173 else
1174 sprintf (buf, "X%02x", status->value.sig);
5b1c542e
PA
1175 break;
1176 default:
1177 error ("unhandled waitkind");
1178 break;
c906108c 1179 }
c906108c
SS
1180}
1181
1182void
fba45db2 1183decode_m_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr)
c906108c
SS
1184{
1185 int i = 0, j = 0;
1186 char ch;
1187 *mem_addr_ptr = *len_ptr = 0;
1188
1189 while ((ch = from[i++]) != ',')
1190 {
1191 *mem_addr_ptr = *mem_addr_ptr << 4;
1192 *mem_addr_ptr |= fromhex (ch) & 0x0f;
1193 }
1194
1195 for (j = 0; j < 4; j++)
1196 {
1197 if ((ch = from[i++]) == 0)
1198 break;
1199 *len_ptr = *len_ptr << 4;
1200 *len_ptr |= fromhex (ch) & 0x0f;
1201 }
1202}
1203
1204void
fba45db2 1205decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
f450004a 1206 unsigned char *to)
c906108c
SS
1207{
1208 int i = 0;
1209 char ch;
1210 *mem_addr_ptr = *len_ptr = 0;
1211
1212 while ((ch = from[i++]) != ',')
1213 {
1214 *mem_addr_ptr = *mem_addr_ptr << 4;
1215 *mem_addr_ptr |= fromhex (ch) & 0x0f;
1216 }
1217
1218 while ((ch = from[i++]) != ':')
1219 {
1220 *len_ptr = *len_ptr << 4;
1221 *len_ptr |= fromhex (ch) & 0x0f;
1222 }
1223
1224 convert_ascii_to_int (&from[i++], to, *len_ptr);
1225}
2f2893d9 1226
01f9e8fa
DJ
1227int
1228decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr,
1229 unsigned int *len_ptr, unsigned char *to)
1230{
1231 int i = 0;
1232 char ch;
1233 *mem_addr_ptr = *len_ptr = 0;
1234
1235 while ((ch = from[i++]) != ',')
1236 {
1237 *mem_addr_ptr = *mem_addr_ptr << 4;
1238 *mem_addr_ptr |= fromhex (ch) & 0x0f;
1239 }
1240
1241 while ((ch = from[i++]) != ':')
1242 {
1243 *len_ptr = *len_ptr << 4;
1244 *len_ptr |= fromhex (ch) & 0x0f;
1245 }
1246
1247 if (remote_unescape_input ((const gdb_byte *) &from[i], packet_len - i,
1248 to, *len_ptr) != *len_ptr)
1249 return -1;
1250
1251 return 0;
1252}
1253
0e7f50da
UW
1254/* Decode a qXfer write request. */
1255int
1256decode_xfer_write (char *buf, int packet_len, char **annex, CORE_ADDR *offset,
1257 unsigned int *len, unsigned char *data)
1258{
1259 char ch;
1260
1261 /* Extract and NUL-terminate the annex. */
1262 *annex = buf;
1263 while (*buf && *buf != ':')
1264 buf++;
1265 if (*buf == '\0')
1266 return -1;
1267 *buf++ = 0;
1268
1269 /* Extract the offset. */
1270 *offset = 0;
1271 while ((ch = *buf++) != ':')
1272 {
1273 *offset = *offset << 4;
1274 *offset |= fromhex (ch) & 0x0f;
1275 }
1276
1277 /* Get encoded data. */
1278 packet_len -= buf - *annex;
1279 *len = remote_unescape_input ((const gdb_byte *) buf, packet_len,
1280 data, packet_len);
1281 return 0;
1282}
1283
08388c79
DE
1284/* Decode the parameters of a qSearch:memory packet. */
1285
1286int
1287decode_search_memory_packet (const char *buf, int packet_len,
1288 CORE_ADDR *start_addrp,
1289 CORE_ADDR *search_space_lenp,
1290 gdb_byte *pattern, unsigned int *pattern_lenp)
1291{
1292 const char *p = buf;
1293
1294 p = decode_address_to_semicolon (start_addrp, p);
1295 p = decode_address_to_semicolon (search_space_lenp, p);
1296 packet_len -= p - buf;
1297 *pattern_lenp = remote_unescape_input ((const gdb_byte *) p, packet_len,
1298 pattern, packet_len);
1299 return 0;
1300}
1301
95954743
PA
1302static void
1303free_sym_cache (struct sym_cache *sym)
1304{
1305 if (sym != NULL)
1306 {
1307 free (sym->name);
1308 free (sym);
1309 }
1310}
1311
1312void
1313clear_symbol_cache (struct sym_cache **symcache_p)
1314{
1315 struct sym_cache *sym, *next;
1316
1317 /* Check the cache first. */
1318 for (sym = *symcache_p; sym; sym = next)
1319 {
1320 next = sym->next;
1321 free_sym_cache (sym);
1322 }
1323
1324 *symcache_p = NULL;
1325}
1326
fd500816
DJ
1327/* Ask GDB for the address of NAME, and return it in ADDRP if found.
1328 Returns 1 if the symbol is found, 0 if it is not, -1 on error. */
1329
2f2893d9
DJ
1330int
1331look_up_one_symbol (const char *name, CORE_ADDR *addrp)
1332{
1333 char own_buf[266], *p, *q;
1334 int len;
fd500816 1335 struct sym_cache *sym;
95954743
PA
1336 struct process_info *proc;
1337
1338 proc = current_process ();
fd500816
DJ
1339
1340 /* Check the cache first. */
95954743 1341 for (sym = proc->symbol_cache; sym; sym = sym->next)
fd500816
DJ
1342 if (strcmp (name, sym->name) == 0)
1343 {
1344 *addrp = sym->addr;
1345 return 1;
1346 }
2f2893d9 1347
ea025f5f
DJ
1348 /* If we've passed the call to thread_db_look_up_symbols, then
1349 anything not in the cache must not exist; we're not interested
1350 in any libraries loaded after that point, only in symbols in
1351 libpthread.so. It might not be an appropriate time to look
1352 up a symbol, e.g. while we're trying to fetch registers. */
95954743 1353 if (proc->all_symbols_looked_up)
ea025f5f
DJ
1354 return 0;
1355
2f2893d9
DJ
1356 /* Send the request. */
1357 strcpy (own_buf, "qSymbol:");
1358 hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
1359 if (putpkt (own_buf) < 0)
1360 return -1;
1361
1362 /* FIXME: Eventually add buffer overflow checking (to getpkt?) */
1363 len = getpkt (own_buf);
1364 if (len < 0)
1365 return -1;
1366
2bbe3cc1
DJ
1367 /* We ought to handle pretty much any packet at this point while we
1368 wait for the qSymbol "response". That requires re-entering the
1369 main loop. For now, this is an adequate approximation; allow
1370 GDB to read from memory while it figures out the address of the
1371 symbol. */
1372 while (own_buf[0] == 'm')
1373 {
1374 CORE_ADDR mem_addr;
1375 unsigned char *mem_buf;
1376 unsigned int mem_len;
1377
1378 decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
bca929d3 1379 mem_buf = xmalloc (mem_len);
2bbe3cc1
DJ
1380 if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
1381 convert_int_to_ascii (mem_buf, own_buf, mem_len);
1382 else
1383 write_enn (own_buf);
1384 free (mem_buf);
1385 if (putpkt (own_buf) < 0)
1386 return -1;
1387 len = getpkt (own_buf);
1388 if (len < 0)
1389 return -1;
1390 }
1b3f6016 1391
2f2893d9
DJ
1392 if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
1393 {
2bbe3cc1 1394 warning ("Malformed response to qSymbol, ignoring: %s\n", own_buf);
2f2893d9
DJ
1395 return -1;
1396 }
1397
1398 p = own_buf + strlen ("qSymbol:");
1399 q = p;
1400 while (*q && *q != ':')
1401 q++;
1402
1403 /* Make sure we found a value for the symbol. */
1404 if (p == q || *q == '\0')
1405 return 0;
1406
1407 decode_address (addrp, p, q - p);
fd500816
DJ
1408
1409 /* Save the symbol in our cache. */
bca929d3
DE
1410 sym = xmalloc (sizeof (*sym));
1411 sym->name = xstrdup (name);
fd500816 1412 sym->addr = *addrp;
95954743
PA
1413 sym->next = proc->symbol_cache;
1414 proc->symbol_cache = sym;
fd500816 1415
2f2893d9
DJ
1416 return 1;
1417}
c74d0ad8
DJ
1418
1419void
bce7165d 1420monitor_output (const char *msg)
c74d0ad8 1421{
bca929d3 1422 char *buf = xmalloc (strlen (msg) * 2 + 2);
c74d0ad8
DJ
1423
1424 buf[0] = 'O';
1425 hexify (buf + 1, msg, 0);
1426
1427 putpkt (buf);
1428 free (buf);
1429}
255e7678
DJ
1430
1431/* Return a malloc allocated string with special characters from TEXT
1432 replaced by entity references. */
1433
1434char *
1435xml_escape_text (const char *text)
1436{
1437 char *result;
1438 int i, special;
1439
1440 /* Compute the length of the result. */
1441 for (i = 0, special = 0; text[i] != '\0'; i++)
1442 switch (text[i])
1443 {
1444 case '\'':
1445 case '\"':
1446 special += 5;
1447 break;
1448 case '&':
1449 special += 4;
1450 break;
1451 case '<':
1452 case '>':
1453 special += 3;
1454 break;
1455 default:
1456 break;
1457 }
1458
1459 /* Expand the result. */
bca929d3 1460 result = xmalloc (i + special + 1);
255e7678
DJ
1461 for (i = 0, special = 0; text[i] != '\0'; i++)
1462 switch (text[i])
1463 {
1464 case '\'':
1465 strcpy (result + i + special, "&apos;");
1466 special += 5;
1467 break;
1468 case '\"':
1469 strcpy (result + i + special, "&quot;");
1470 special += 5;
1471 break;
1472 case '&':
1473 strcpy (result + i + special, "&amp;");
1474 special += 4;
1475 break;
1476 case '<':
1477 strcpy (result + i + special, "&lt;");
1478 special += 3;
1479 break;
1480 case '>':
1481 strcpy (result + i + special, "&gt;");
1482 special += 3;
1483 break;
1484 default:
1485 result[i + special] = text[i];
1486 break;
1487 }
1488 result[i + special] = '\0';
1489
1490 return result;
1491}
07e059b5
VP
1492
1493void
1494buffer_grow (struct buffer *buffer, const char *data, size_t size)
1495{
1496 char *new_buffer;
1497 size_t new_buffer_size;
1498
1499 if (size == 0)
1500 return;
1501
1502 new_buffer_size = buffer->buffer_size;
1503
1504 if (new_buffer_size == 0)
1505 new_buffer_size = 1;
1506
1507 while (buffer->used_size + size > new_buffer_size)
1508 new_buffer_size *= 2;
1509 new_buffer = realloc (buffer->buffer, new_buffer_size);
1510 if (!new_buffer)
1511 abort ();
1512 memcpy (new_buffer + buffer->used_size, data, size);
1513 buffer->buffer = new_buffer;
1514 buffer->buffer_size = new_buffer_size;
1515 buffer->used_size += size;
1516}
1517
1518void
1519buffer_free (struct buffer *buffer)
1520{
1521 if (!buffer)
1522 return;
1523
1524 free (buffer->buffer);
1525 buffer->buffer = NULL;
1526 buffer->buffer_size = 0;
1527 buffer->used_size = 0;
1528}
1529
1530void
1531buffer_init (struct buffer *buffer)
1532{
1533 memset (buffer, 0, sizeof (*buffer));
1534}
1535
1536char*
1537buffer_finish (struct buffer *buffer)
1538{
1539 char *ret = buffer->buffer;
1540 buffer->buffer = NULL;
1541 buffer->buffer_size = 0;
1542 buffer->used_size = 0;
1543 return ret;
1544}
1545
1546void
1547buffer_xml_printf (struct buffer *buffer, const char *format, ...)
1548{
1549 va_list ap;
1550 const char *f;
1551 const char *prev;
1552 int percent = 0;
1553
1554 va_start (ap, format);
1555
1556 prev = format;
1557 for (f = format; *f; f++)
1558 {
1559 if (percent)
1560 {
1b3f6016
PA
1561 switch (*f)
1562 {
1563 case 's':
1564 {
1565 char *p;
1566 char *a = va_arg (ap, char *);
1567 buffer_grow (buffer, prev, f - prev - 1);
1568 p = xml_escape_text (a);
1569 buffer_grow_str (buffer, p);
1570 free (p);
1571 prev = f + 1;
1572 }
1573 break;
1574 }
1575 percent = 0;
07e059b5
VP
1576 }
1577 else if (*f == '%')
1578 percent = 1;
1579 }
1580
1581 buffer_grow_str (buffer, prev);
1582 va_end (ap);
1583}