]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/serial.c
Rewrote i386_index_check
[thirdparty/binutils-gdb.git] / gdb / serial.c
CommitLineData
c906108c 1/* Generic serial interface routines
4fcf66da 2
28e7fd62 3 Copyright (C) 1992-2013 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
19
20#include "defs.h"
21#include <ctype.h>
22#include "serial.h"
23#include "gdb_string.h"
24#include "gdbcmd.h"
25
c2c6d25f 26extern void _initialize_serial (void);
392a587b 27
c378eb4e 28/* Is serial being debugged? */
2acceee2 29
ccce17b0 30static unsigned int global_serial_debug_p;
2acceee2 31
c378eb4e 32/* Linked list of serial I/O handlers. */
c906108c
SS
33
34static struct serial_ops *serial_ops_list = NULL;
35
5eb3b062
PA
36/* Pointer to list of scb's. */
37
38static struct serial *scb_base;
39
c906108c 40/* Non-NULL gives filename which contains a recording of the remote session,
c378eb4e 41 suitable for playback by gdbserver. */
c906108c
SS
42
43static char *serial_logfile = NULL;
d9fcf2fb 44static struct ui_file *serial_logfp = NULL;
c906108c 45
58f07bae 46static struct serial_ops *serial_interface_lookup (const char *);
3e43a32a
MS
47static void serial_logchar (struct ui_file *stream,
48 int ch_type, int ch, int timeout);
53904c9e
AC
49static const char logbase_hex[] = "hex";
50static const char logbase_octal[] = "octal";
51static const char logbase_ascii[] = "ascii";
40478521 52static const char *const logbase_enums[] =
c5aa993b 53{logbase_hex, logbase_octal, logbase_ascii, NULL};
53904c9e 54static const char *serial_logbase = logbase_ascii;
c906108c 55\f
c5aa993b 56
c906108c
SS
57static int serial_current_type = 0;
58
c378eb4e 59/* Log char CH of type CHTYPE, with TIMEOUT. */
c906108c
SS
60
61/* Define bogus char to represent a BREAK. Should be careful to choose a value
62 that can't be confused with a normal char, or an error code. */
63#define SERIAL_BREAK 1235
64
65static void
d9fcf2fb 66serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
c906108c
SS
67{
68 if (ch_type != serial_current_type)
69 {
2acceee2 70 fprintf_unfiltered (stream, "\n%c ", ch_type);
c906108c
SS
71 serial_current_type = ch_type;
72 }
73
74 if (serial_logbase != logbase_ascii)
2acceee2 75 fputc_unfiltered (' ', stream);
c906108c
SS
76
77 switch (ch)
78 {
79 case SERIAL_TIMEOUT:
2acceee2 80 fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
c906108c
SS
81 return;
82 case SERIAL_ERROR:
2acceee2 83 fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
c906108c
SS
84 return;
85 case SERIAL_EOF:
2acceee2 86 fputs_unfiltered ("<Eof>", stream);
c906108c
SS
87 return;
88 case SERIAL_BREAK:
2acceee2 89 fputs_unfiltered ("<Break>", stream);
c906108c
SS
90 return;
91 default:
92 if (serial_logbase == logbase_hex)
2acceee2 93 fprintf_unfiltered (stream, "%02x", ch & 0xff);
c906108c 94 else if (serial_logbase == logbase_octal)
2acceee2 95 fprintf_unfiltered (stream, "%03o", ch & 0xff);
c906108c
SS
96 else
97 switch (ch)
98 {
c5aa993b 99 case '\\':
2acceee2 100 fputs_unfiltered ("\\\\", stream);
c5aa993b
JM
101 break;
102 case '\b':
2acceee2 103 fputs_unfiltered ("\\b", stream);
c5aa993b
JM
104 break;
105 case '\f':
2acceee2 106 fputs_unfiltered ("\\f", stream);
c5aa993b
JM
107 break;
108 case '\n':
2acceee2 109 fputs_unfiltered ("\\n", stream);
c5aa993b
JM
110 break;
111 case '\r':
2acceee2 112 fputs_unfiltered ("\\r", stream);
c5aa993b
JM
113 break;
114 case '\t':
2acceee2 115 fputs_unfiltered ("\\t", stream);
c5aa993b
JM
116 break;
117 case '\v':
2acceee2 118 fputs_unfiltered ("\\v", stream);
c5aa993b
JM
119 break;
120 default:
3e43a32a
MS
121 fprintf_unfiltered (stream,
122 isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
c5aa993b 123 break;
c906108c
SS
124 }
125 }
126}
127
128void
c2c6d25f 129serial_log_command (const char *cmd)
c906108c
SS
130{
131 if (!serial_logfp)
132 return;
133
134 serial_current_type = 'c';
135
136 fputs_unfiltered ("\nc ", serial_logfp);
137 fputs_unfiltered (cmd, serial_logfp);
138
139 /* Make sure that the log file is as up-to-date as possible,
c378eb4e 140 in case we are getting ready to dump core or something. */
c906108c
SS
141 gdb_flush (serial_logfp);
142}
143
c2c6d25f 144\f
c906108c 145static struct serial_ops *
58f07bae 146serial_interface_lookup (const char *name)
c906108c
SS
147{
148 struct serial_ops *ops;
149
150 for (ops = serial_ops_list; ops; ops = ops->next)
151 if (strcmp (name, ops->name) == 0)
152 return ops;
153
154 return NULL;
155}
156
157void
c2c6d25f 158serial_add_interface (struct serial_ops *optable)
c906108c
SS
159{
160 optable->next = serial_ops_list;
161 serial_ops_list = optable;
162}
163
5eb3b062
PA
164/* Return the open serial device for FD, if found, or NULL if FD is
165 not already opened. */
166
167struct serial *
168serial_for_fd (int fd)
169{
170 struct serial *scb;
171
172 for (scb = scb_base; scb; scb = scb->next)
173 if (scb->fd == fd)
174 return scb;
175
176 return NULL;
177}
178
c378eb4e 179/* Open up a device or a network socket, depending upon the syntax of NAME. */
c906108c 180
819cc324 181struct serial *
c2c6d25f 182serial_open (const char *name)
c906108c 183{
819cc324 184 struct serial *scb;
c906108c 185 struct serial_ops *ops;
c2c6d25f 186 const char *open_name = name;
c906108c 187
50a9e2f1 188 if (strcmp (name, "pc") == 0)
c906108c 189 ops = serial_interface_lookup ("pc");
c906108c
SS
190 else if (strncmp (name, "lpt", 3) == 0)
191 ops = serial_interface_lookup ("parallel");
43e526b9 192 else if (strncmp (name, "|", 1) == 0)
c2c6d25f
JM
193 {
194 ops = serial_interface_lookup ("pipe");
8b9e3a15
VP
195 /* Discard ``|'' and any space before the command itself. */
196 ++open_name;
197 while (isspace (*open_name))
198 ++open_name;
c2c6d25f 199 }
2821caf1
JB
200 /* Check for a colon, suggesting an IP address/port pair.
201 Do this *after* checking for all the interesting prefixes. We
202 don't want to constrain the syntax of what can follow them. */
203 else if (strchr (name, ':'))
204 ops = serial_interface_lookup ("tcp");
c906108c
SS
205 else
206 ops = serial_interface_lookup ("hardwire");
207
208 if (!ops)
209 return NULL;
210
65e2f740 211 scb = XMALLOC (struct serial);
c906108c
SS
212
213 scb->ops = ops;
214
215 scb->bufcnt = 0;
216 scb->bufp = scb->buf;
65cc4390 217 scb->error_fd = -1;
ddefb60f 218 scb->refcnt = 1;
c906108c 219
766062f6 220 /* `...->open (...)' would get expanded by the open(2) syscall macro. */
652aaa24 221 if ((*scb->ops->open) (scb, open_name))
c906108c 222 {
b8c9b27d 223 xfree (scb);
c906108c
SS
224 return NULL;
225 }
226
4fcf66da 227 scb->name = xstrdup (name);
5eb3b062 228 scb->next = scb_base;
2acceee2
JM
229 scb->debug_p = 0;
230 scb->async_state = 0;
c2c6d25f
JM
231 scb->async_handler = NULL;
232 scb->async_context = NULL;
5eb3b062 233 scb_base = scb;
c906108c
SS
234
235 if (serial_logfile != NULL)
236 {
237 serial_logfp = gdb_fopen (serial_logfile, "w");
238 if (serial_logfp == NULL)
239 perror_with_name (serial_logfile);
240 }
241
242 return scb;
243}
244
58f07bae
PA
245/* Open a new serial stream using a file handle, using serial
246 interface ops OPS. */
247
248static struct serial *
249serial_fdopen_ops (const int fd, struct serial_ops *ops)
c906108c 250{
819cc324 251 struct serial *scb;
c906108c 252
0ea3f30e 253 if (!ops)
58f07bae
PA
254 {
255 ops = serial_interface_lookup ("terminal");
256 if (!ops)
257 ops = serial_interface_lookup ("hardwire");
258 }
c906108c
SS
259
260 if (!ops)
261 return NULL;
262
0ea3f30e 263 scb = XCALLOC (1, struct serial);
c906108c
SS
264
265 scb->ops = ops;
266
267 scb->bufcnt = 0;
268 scb->bufp = scb->buf;
58f07bae 269 scb->error_fd = -1;
ddefb60f 270 scb->refcnt = 1;
c906108c
SS
271
272 scb->name = NULL;
5eb3b062 273 scb->next = scb_base;
2acceee2
JM
274 scb->debug_p = 0;
275 scb->async_state = 0;
c2c6d25f
JM
276 scb->async_handler = NULL;
277 scb->async_context = NULL;
5eb3b062 278 scb_base = scb;
c906108c 279
58f07bae
PA
280 if ((ops->fdopen) != NULL)
281 (*ops->fdopen) (scb, fd);
282 else
283 scb->fd = fd;
284
c906108c
SS
285 return scb;
286}
287
58f07bae
PA
288struct serial *
289serial_fdopen (const int fd)
290{
291 return serial_fdopen_ops (fd, NULL);
292}
293
c2c6d25f 294static void
819cc324 295do_serial_close (struct serial *scb, int really_close)
c906108c 296{
819cc324 297 struct serial *tmp_scb;
c906108c 298
c906108c
SS
299 if (serial_logfp)
300 {
301 fputs_unfiltered ("\nEnd of log\n", serial_logfp);
302 serial_current_type = 0;
303
c378eb4e 304 /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
d9fcf2fb 305 ui_file_delete (serial_logfp);
c906108c
SS
306 serial_logfp = NULL;
307 }
308
c378eb4e 309 /* ensure that the FD has been taken out of async mode. */
c2c6d25f
JM
310 if (scb->async_handler != NULL)
311 serial_async (scb, NULL, NULL);
312
c906108c
SS
313 if (really_close)
314 scb->ops->close (scb);
315
316 if (scb->name)
b8c9b27d 317 xfree (scb->name);
c906108c 318
ddefb60f
PA
319 /* For serial_is_open. */
320 scb->bufp = NULL;
321
5eb3b062
PA
322 if (scb_base == scb)
323 scb_base = scb_base->next;
324 else
325 for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
326 {
327 if (tmp_scb->next != scb)
328 continue;
329
330 tmp_scb->next = tmp_scb->next->next;
331 break;
332 }
333
ddefb60f 334 serial_unref (scb);
c906108c
SS
335}
336
c2c6d25f 337void
819cc324 338serial_close (struct serial *scb)
c2c6d25f
JM
339{
340 do_serial_close (scb, 1);
341}
342
343void
819cc324 344serial_un_fdopen (struct serial *scb)
c2c6d25f
JM
345{
346 do_serial_close (scb, 0);
347}
348
ddefb60f
PA
349int
350serial_is_open (struct serial *scb)
351{
352 return scb->bufp != NULL;
353}
354
355void
356serial_ref (struct serial *scb)
357{
358 scb->refcnt++;
359}
360
361void
362serial_unref (struct serial *scb)
363{
364 --scb->refcnt;
365 if (scb->refcnt == 0)
366 xfree (scb);
367}
368
c2c6d25f 369int
819cc324 370serial_readchar (struct serial *scb, int timeout)
c2c6d25f
JM
371{
372 int ch;
373
2df3850c 374 /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
c378eb4e 375 code is finished. */
2cd58942 376 if (0 && serial_is_async_p (scb) && timeout < 0)
8e65ff28 377 internal_error (__FILE__, __LINE__,
e2e0b3e5 378 _("serial_readchar: blocking read in async mode"));
2df3850c 379
c2c6d25f
JM
380 ch = scb->ops->readchar (scb, timeout);
381 if (serial_logfp != NULL)
382 {
2acceee2 383 serial_logchar (serial_logfp, 'r', ch, timeout);
c2c6d25f
JM
384
385 /* Make sure that the log file is as up-to-date as possible,
c378eb4e 386 in case we are getting ready to dump core or something. */
c2c6d25f
JM
387 gdb_flush (serial_logfp);
388 }
2cd58942 389 if (serial_debug_p (scb))
2acceee2
JM
390 {
391 fprintf_unfiltered (gdb_stdlog, "[");
392 serial_logchar (gdb_stdlog, 'r', ch, timeout);
393 fprintf_unfiltered (gdb_stdlog, "]");
394 gdb_flush (gdb_stdlog);
395 }
c2c6d25f
JM
396
397 return (ch);
398}
399
400int
819cc324 401serial_write (struct serial *scb, const char *str, int len)
c2c6d25f
JM
402{
403 if (serial_logfp != NULL)
404 {
405 int count;
406
407 for (count = 0; count < len; count++)
2acceee2 408 serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
c2c6d25f
JM
409
410 /* Make sure that the log file is as up-to-date as possible,
c378eb4e 411 in case we are getting ready to dump core or something. */
c2c6d25f
JM
412 gdb_flush (serial_logfp);
413 }
9214d371
DE
414 if (serial_debug_p (scb))
415 {
416 int count;
417
418 for (count = 0; count < len; count++)
419 {
420 fprintf_unfiltered (gdb_stdlog, "[");
421 serial_logchar (gdb_stdlog, 'w', str[count] & 0xff, 0);
422 fprintf_unfiltered (gdb_stdlog, "]");
423 }
424 gdb_flush (gdb_stdlog);
425 }
c2c6d25f
JM
426
427 return (scb->ops->write (scb, str, len));
428}
429
430void
819cc324 431serial_printf (struct serial *desc, const char *format,...)
c2c6d25f
JM
432{
433 va_list args;
434 char *buf;
435 va_start (args, format);
436
e623b504 437 buf = xstrvprintf (format, args);
2cd58942 438 serial_write (desc, buf, strlen (buf));
c2c6d25f 439
b8c9b27d 440 xfree (buf);
c2c6d25f
JM
441 va_end (args);
442}
443
444int
819cc324 445serial_drain_output (struct serial *scb)
c2c6d25f
JM
446{
447 return scb->ops->drain_output (scb);
448}
449
450int
819cc324 451serial_flush_output (struct serial *scb)
c2c6d25f
JM
452{
453 return scb->ops->flush_output (scb);
454}
455
456int
819cc324 457serial_flush_input (struct serial *scb)
c2c6d25f
JM
458{
459 return scb->ops->flush_input (scb);
460}
461
462int
819cc324 463serial_send_break (struct serial *scb)
c2c6d25f
JM
464{
465 if (serial_logfp != NULL)
2acceee2 466 serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
c2c6d25f
JM
467
468 return (scb->ops->send_break (scb));
469}
470
471void
819cc324 472serial_raw (struct serial *scb)
c2c6d25f
JM
473{
474 scb->ops->go_raw (scb);
475}
476
477serial_ttystate
819cc324 478serial_get_tty_state (struct serial *scb)
c2c6d25f
JM
479{
480 return scb->ops->get_tty_state (scb);
481}
482
1e182ce8
UW
483serial_ttystate
484serial_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
485{
486 return scb->ops->copy_tty_state (scb, ttystate);
487}
488
c2c6d25f 489int
819cc324 490serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
c2c6d25f
JM
491{
492 return scb->ops->set_tty_state (scb, ttystate);
493}
494
495void
819cc324 496serial_print_tty_state (struct serial *scb,
c2c6d25f 497 serial_ttystate ttystate,
d9fcf2fb 498 struct ui_file *stream)
c2c6d25f
JM
499{
500 scb->ops->print_tty_state (scb, ttystate, stream);
501}
502
503int
819cc324 504serial_noflush_set_tty_state (struct serial *scb,
c2c6d25f
JM
505 serial_ttystate new_ttystate,
506 serial_ttystate old_ttystate)
507{
508 return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
509}
510
511int
819cc324 512serial_setbaudrate (struct serial *scb, int rate)
c2c6d25f
JM
513{
514 return scb->ops->setbaudrate (scb, rate);
515}
516
517int
819cc324 518serial_setstopbits (struct serial *scb, int num)
c2c6d25f
JM
519{
520 return scb->ops->setstopbits (scb, num);
521}
522
523int
819cc324 524serial_can_async_p (struct serial *scb)
c2c6d25f
JM
525{
526 return (scb->ops->async != NULL);
527}
528
529int
819cc324 530serial_is_async_p (struct serial *scb)
c2c6d25f
JM
531{
532 return (scb->ops->async != NULL) && (scb->async_handler != NULL);
533}
534
535void
819cc324 536serial_async (struct serial *scb,
c2c6d25f
JM
537 serial_event_ftype *handler,
538 void *context)
539{
05ce04a4 540 int changed = ((scb->async_handler == NULL) != (handler == NULL));
433759f7 541
c2c6d25f
JM
542 scb->async_handler = handler;
543 scb->async_context = context;
05ce04a4
VP
544 /* Only change mode if there is a need. */
545 if (changed)
546 scb->ops->async (scb, handler != NULL);
c2c6d25f
JM
547}
548
2acceee2 549void
819cc324 550serial_debug (struct serial *scb, int debug_p)
2acceee2
JM
551{
552 scb->debug_p = debug_p;
553}
554
555int
819cc324 556serial_debug_p (struct serial *scb)
2acceee2
JM
557{
558 return scb->debug_p || global_serial_debug_p;
559}
560
0ea3f30e
DJ
561#ifdef USE_WIN32API
562void
563serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
564{
565 if (scb->ops->wait_handle)
566 scb->ops->wait_handle (scb, read, except);
567 else
568 {
569 *read = (HANDLE) _get_osfhandle (scb->fd);
570 *except = NULL;
571 }
572}
c3e2b812
DJ
573
574void
575serial_done_wait_handle (struct serial *scb)
576{
577 if (scb->ops->done_wait_handle)
578 scb->ops->done_wait_handle (scb);
579}
0ea3f30e 580#endif
2acceee2 581
58f07bae
PA
582int
583serial_pipe (struct serial *scbs[2])
584{
585 struct serial_ops *ops;
586 int fildes[2];
587
588 ops = serial_interface_lookup ("pipe");
589 if (!ops)
590 {
591 errno = ENOSYS;
592 return -1;
593 }
594
595 if (gdb_pipe (fildes) == -1)
596 return -1;
597
598 scbs[0] = serial_fdopen_ops (fildes[0], ops);
599 scbs[1] = serial_fdopen_ops (fildes[1], ops);
600 return 0;
601}
602
e3abfe1d
AC
603/* Serial set/show framework. */
604
605static struct cmd_list_element *serial_set_cmdlist;
606static struct cmd_list_element *serial_show_cmdlist;
607
608static void
609serial_set_cmd (char *args, int from_tty)
610{
3e43a32a
MS
611 printf_unfiltered ("\"set serial\" must be followed "
612 "by the name of a command.\n");
e3abfe1d
AC
613 help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
614}
615
616static void
617serial_show_cmd (char *args, int from_tty)
618{
619 cmd_show_list (serial_show_cmdlist, from_tty, "");
620}
621
622
c906108c 623void
c2c6d25f 624_initialize_serial (void)
c906108c
SS
625{
626#if 0
1bedd215
AC
627 add_com ("connect", class_obscure, connect_command, _("\
628Connect the terminal directly up to the command monitor.\n\
629Use <CR>~. or <CR>~^D to break out."));
c906108c
SS
630#endif /* 0 */
631
1bedd215
AC
632 add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
633Set default serial/parallel port configuration."),
e3abfe1d
AC
634 &serial_set_cmdlist, "set serial ",
635 0/*allow-unknown*/,
636 &setlist);
637
1bedd215
AC
638 add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
639Show default serial/parallel port configuration."),
e3abfe1d
AC
640 &serial_show_cmdlist, "show serial ",
641 0/*allow-unknown*/,
642 &showlist);
643
f397e303
AC
644 add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
645Set filename for remote session recording."), _("\
646Show filename for remote session recording."), _("\
c906108c 647This file is used to record the remote session for future playback\n\
f397e303
AC
648by gdbserver."),
649 NULL,
650 NULL, /* FIXME: i18n: */
651 &setlist, &showlist);
c906108c 652
7ab04401
AC
653 add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
654 &serial_logbase, _("\
655Set numerical base for remote session logging"), _("\
656Show numerical base for remote session logging"), NULL,
657 NULL,
658 NULL, /* FIXME: i18n: */
659 &setlist, &showlist);
2acceee2 660
ccce17b0
YQ
661 add_setshow_zuinteger_cmd ("serial", class_maintenance,
662 &global_serial_debug_p, _("\
85c07804
AC
663Set serial debugging."), _("\
664Show serial debugging."), _("\
665When non-zero, serial port debugging is enabled."),
ccce17b0
YQ
666 NULL,
667 NULL, /* FIXME: i18n: */
668 &setdebuglist, &showdebuglist);
c906108c 669}