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