GDB (API)
|
00001 /* Generic serial interface routines 00002 00003 Copyright (C) 1992-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include <ctype.h> 00022 #include "serial.h" 00023 #include "gdb_string.h" 00024 #include "gdbcmd.h" 00025 #include "cli/cli-utils.h" 00026 00027 extern void _initialize_serial (void); 00028 00029 /* Is serial being debugged? */ 00030 00031 static unsigned int global_serial_debug_p; 00032 00033 /* Linked list of serial I/O handlers. */ 00034 00035 static struct serial_ops *serial_ops_list = NULL; 00036 00037 /* Pointer to list of scb's. */ 00038 00039 static struct serial *scb_base; 00040 00041 /* Non-NULL gives filename which contains a recording of the remote session, 00042 suitable for playback by gdbserver. */ 00043 00044 static char *serial_logfile = NULL; 00045 static struct ui_file *serial_logfp = NULL; 00046 00047 static struct serial_ops *serial_interface_lookup (const char *); 00048 static void serial_logchar (struct ui_file *stream, 00049 int ch_type, int ch, int timeout); 00050 static const char logbase_hex[] = "hex"; 00051 static const char logbase_octal[] = "octal"; 00052 static const char logbase_ascii[] = "ascii"; 00053 static const char *const logbase_enums[] = 00054 {logbase_hex, logbase_octal, logbase_ascii, NULL}; 00055 static const char *serial_logbase = logbase_ascii; 00056 00057 00058 static int serial_current_type = 0; 00059 00060 /* Log char CH of type CHTYPE, with TIMEOUT. */ 00061 00062 /* Define bogus char to represent a BREAK. Should be careful to choose a value 00063 that can't be confused with a normal char, or an error code. */ 00064 #define SERIAL_BREAK 1235 00065 00066 static void 00067 serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout) 00068 { 00069 if (ch_type != serial_current_type) 00070 { 00071 fprintf_unfiltered (stream, "\n%c ", ch_type); 00072 serial_current_type = ch_type; 00073 } 00074 00075 if (serial_logbase != logbase_ascii) 00076 fputc_unfiltered (' ', stream); 00077 00078 switch (ch) 00079 { 00080 case SERIAL_TIMEOUT: 00081 fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout); 00082 return; 00083 case SERIAL_ERROR: 00084 fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno)); 00085 return; 00086 case SERIAL_EOF: 00087 fputs_unfiltered ("<Eof>", stream); 00088 return; 00089 case SERIAL_BREAK: 00090 fputs_unfiltered ("<Break>", stream); 00091 return; 00092 default: 00093 if (serial_logbase == logbase_hex) 00094 fprintf_unfiltered (stream, "%02x", ch & 0xff); 00095 else if (serial_logbase == logbase_octal) 00096 fprintf_unfiltered (stream, "%03o", ch & 0xff); 00097 else 00098 switch (ch) 00099 { 00100 case '\\': 00101 fputs_unfiltered ("\\\\", stream); 00102 break; 00103 case '\b': 00104 fputs_unfiltered ("\\b", stream); 00105 break; 00106 case '\f': 00107 fputs_unfiltered ("\\f", stream); 00108 break; 00109 case '\n': 00110 fputs_unfiltered ("\\n", stream); 00111 break; 00112 case '\r': 00113 fputs_unfiltered ("\\r", stream); 00114 break; 00115 case '\t': 00116 fputs_unfiltered ("\\t", stream); 00117 break; 00118 case '\v': 00119 fputs_unfiltered ("\\v", stream); 00120 break; 00121 default: 00122 fprintf_unfiltered (stream, 00123 isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF); 00124 break; 00125 } 00126 } 00127 } 00128 00129 void 00130 serial_log_command (const char *cmd) 00131 { 00132 if (!serial_logfp) 00133 return; 00134 00135 serial_current_type = 'c'; 00136 00137 fputs_unfiltered ("\nc ", serial_logfp); 00138 fputs_unfiltered (cmd, serial_logfp); 00139 00140 /* Make sure that the log file is as up-to-date as possible, 00141 in case we are getting ready to dump core or something. */ 00142 gdb_flush (serial_logfp); 00143 } 00144 00145 00146 static struct serial_ops * 00147 serial_interface_lookup (const char *name) 00148 { 00149 struct serial_ops *ops; 00150 00151 for (ops = serial_ops_list; ops; ops = ops->next) 00152 if (strcmp (name, ops->name) == 0) 00153 return ops; 00154 00155 return NULL; 00156 } 00157 00158 void 00159 serial_add_interface (struct serial_ops *optable) 00160 { 00161 optable->next = serial_ops_list; 00162 serial_ops_list = optable; 00163 } 00164 00165 /* Return the open serial device for FD, if found, or NULL if FD is 00166 not already opened. */ 00167 00168 struct serial * 00169 serial_for_fd (int fd) 00170 { 00171 struct serial *scb; 00172 00173 for (scb = scb_base; scb; scb = scb->next) 00174 if (scb->fd == fd) 00175 return scb; 00176 00177 return NULL; 00178 } 00179 00180 /* Open up a device or a network socket, depending upon the syntax of NAME. */ 00181 00182 struct serial * 00183 serial_open (const char *name) 00184 { 00185 struct serial *scb; 00186 struct serial_ops *ops; 00187 const char *open_name = name; 00188 00189 if (strcmp (name, "pc") == 0) 00190 ops = serial_interface_lookup ("pc"); 00191 else if (strncmp (name, "lpt", 3) == 0) 00192 ops = serial_interface_lookup ("parallel"); 00193 else if (strncmp (name, "|", 1) == 0) 00194 { 00195 ops = serial_interface_lookup ("pipe"); 00196 /* Discard ``|'' and any space before the command itself. */ 00197 ++open_name; 00198 open_name = skip_spaces_const (open_name); 00199 } 00200 /* Check for a colon, suggesting an IP address/port pair. 00201 Do this *after* checking for all the interesting prefixes. We 00202 don't want to constrain the syntax of what can follow them. */ 00203 else if (strchr (name, ':')) 00204 ops = serial_interface_lookup ("tcp"); 00205 else 00206 ops = serial_interface_lookup ("hardwire"); 00207 00208 if (!ops) 00209 return NULL; 00210 00211 scb = XMALLOC (struct serial); 00212 00213 scb->ops = ops; 00214 00215 scb->bufcnt = 0; 00216 scb->bufp = scb->buf; 00217 scb->error_fd = -1; 00218 scb->refcnt = 1; 00219 00220 /* `...->open (...)' would get expanded by the open(2) syscall macro. */ 00221 if ((*scb->ops->open) (scb, open_name)) 00222 { 00223 xfree (scb); 00224 return NULL; 00225 } 00226 00227 scb->name = xstrdup (name); 00228 scb->next = scb_base; 00229 scb->debug_p = 0; 00230 scb->async_state = 0; 00231 scb->async_handler = NULL; 00232 scb->async_context = NULL; 00233 scb_base = scb; 00234 00235 if (serial_logfile != NULL) 00236 { 00237 serial_logfp = gdb_fopen (serial_logfile, "w"); 00238 if (serial_logfp == NULL) 00239 perror_with_name (serial_logfile); 00240 } 00241 00242 return scb; 00243 } 00244 00245 /* Open a new serial stream using a file handle, using serial 00246 interface ops OPS. */ 00247 00248 static struct serial * 00249 serial_fdopen_ops (const int fd, struct serial_ops *ops) 00250 { 00251 struct serial *scb; 00252 00253 if (!ops) 00254 { 00255 ops = serial_interface_lookup ("terminal"); 00256 if (!ops) 00257 ops = serial_interface_lookup ("hardwire"); 00258 } 00259 00260 if (!ops) 00261 return NULL; 00262 00263 scb = XCALLOC (1, struct serial); 00264 00265 scb->ops = ops; 00266 00267 scb->bufcnt = 0; 00268 scb->bufp = scb->buf; 00269 scb->error_fd = -1; 00270 scb->refcnt = 1; 00271 00272 scb->name = NULL; 00273 scb->next = scb_base; 00274 scb->debug_p = 0; 00275 scb->async_state = 0; 00276 scb->async_handler = NULL; 00277 scb->async_context = NULL; 00278 scb_base = scb; 00279 00280 if ((ops->fdopen) != NULL) 00281 (*ops->fdopen) (scb, fd); 00282 else 00283 scb->fd = fd; 00284 00285 return scb; 00286 } 00287 00288 struct serial * 00289 serial_fdopen (const int fd) 00290 { 00291 return serial_fdopen_ops (fd, NULL); 00292 } 00293 00294 static void 00295 do_serial_close (struct serial *scb, int really_close) 00296 { 00297 struct serial *tmp_scb; 00298 00299 if (serial_logfp) 00300 { 00301 fputs_unfiltered ("\nEnd of log\n", serial_logfp); 00302 serial_current_type = 0; 00303 00304 /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */ 00305 ui_file_delete (serial_logfp); 00306 serial_logfp = NULL; 00307 } 00308 00309 /* ensure that the FD has been taken out of async mode. */ 00310 if (scb->async_handler != NULL) 00311 serial_async (scb, NULL, NULL); 00312 00313 if (really_close) 00314 scb->ops->close (scb); 00315 00316 if (scb->name) 00317 xfree (scb->name); 00318 00319 /* For serial_is_open. */ 00320 scb->bufp = NULL; 00321 00322 if (scb_base == scb) 00323 scb_base = scb_base->next; 00324 else 00325 for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next) 00326 { 00327 if (tmp_scb->next != scb) 00328 continue; 00329 00330 tmp_scb->next = tmp_scb->next->next; 00331 break; 00332 } 00333 00334 serial_unref (scb); 00335 } 00336 00337 void 00338 serial_close (struct serial *scb) 00339 { 00340 do_serial_close (scb, 1); 00341 } 00342 00343 void 00344 serial_un_fdopen (struct serial *scb) 00345 { 00346 do_serial_close (scb, 0); 00347 } 00348 00349 int 00350 serial_is_open (struct serial *scb) 00351 { 00352 return scb->bufp != NULL; 00353 } 00354 00355 void 00356 serial_ref (struct serial *scb) 00357 { 00358 scb->refcnt++; 00359 } 00360 00361 void 00362 serial_unref (struct serial *scb) 00363 { 00364 --scb->refcnt; 00365 if (scb->refcnt == 0) 00366 xfree (scb); 00367 } 00368 00369 int 00370 serial_readchar (struct serial *scb, int timeout) 00371 { 00372 int ch; 00373 00374 /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC 00375 code is finished. */ 00376 if (0 && serial_is_async_p (scb) && timeout < 0) 00377 internal_error (__FILE__, __LINE__, 00378 _("serial_readchar: blocking read in async mode")); 00379 00380 ch = scb->ops->readchar (scb, timeout); 00381 if (serial_logfp != NULL) 00382 { 00383 serial_logchar (serial_logfp, 'r', ch, timeout); 00384 00385 /* Make sure that the log file is as up-to-date as possible, 00386 in case we are getting ready to dump core or something. */ 00387 gdb_flush (serial_logfp); 00388 } 00389 if (serial_debug_p (scb)) 00390 { 00391 fprintf_unfiltered (gdb_stdlog, "["); 00392 serial_logchar (gdb_stdlog, 'r', ch, timeout); 00393 fprintf_unfiltered (gdb_stdlog, "]"); 00394 gdb_flush (gdb_stdlog); 00395 } 00396 00397 return (ch); 00398 } 00399 00400 int 00401 serial_write (struct serial *scb, const void *buf, size_t count) 00402 { 00403 if (serial_logfp != NULL) 00404 { 00405 const char *str = buf; 00406 size_t c; 00407 00408 for (c = 0; c < count; c++) 00409 serial_logchar (serial_logfp, 'w', str[c] & 0xff, 0); 00410 00411 /* Make sure that the log file is as up-to-date as possible, 00412 in case we are getting ready to dump core or something. */ 00413 gdb_flush (serial_logfp); 00414 } 00415 if (serial_debug_p (scb)) 00416 { 00417 const char *str = buf; 00418 size_t c; 00419 00420 for (c = 0; c < count; c++) 00421 { 00422 fprintf_unfiltered (gdb_stdlog, "["); 00423 serial_logchar (gdb_stdlog, 'w', str[count] & 0xff, 0); 00424 fprintf_unfiltered (gdb_stdlog, "]"); 00425 } 00426 gdb_flush (gdb_stdlog); 00427 } 00428 00429 return (scb->ops->write (scb, buf, count)); 00430 } 00431 00432 void 00433 serial_printf (struct serial *desc, const char *format,...) 00434 { 00435 va_list args; 00436 char *buf; 00437 va_start (args, format); 00438 00439 buf = xstrvprintf (format, args); 00440 serial_write (desc, buf, strlen (buf)); 00441 00442 xfree (buf); 00443 va_end (args); 00444 } 00445 00446 int 00447 serial_drain_output (struct serial *scb) 00448 { 00449 return scb->ops->drain_output (scb); 00450 } 00451 00452 int 00453 serial_flush_output (struct serial *scb) 00454 { 00455 return scb->ops->flush_output (scb); 00456 } 00457 00458 int 00459 serial_flush_input (struct serial *scb) 00460 { 00461 return scb->ops->flush_input (scb); 00462 } 00463 00464 int 00465 serial_send_break (struct serial *scb) 00466 { 00467 if (serial_logfp != NULL) 00468 serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0); 00469 00470 return (scb->ops->send_break (scb)); 00471 } 00472 00473 void 00474 serial_raw (struct serial *scb) 00475 { 00476 scb->ops->go_raw (scb); 00477 } 00478 00479 serial_ttystate 00480 serial_get_tty_state (struct serial *scb) 00481 { 00482 return scb->ops->get_tty_state (scb); 00483 } 00484 00485 serial_ttystate 00486 serial_copy_tty_state (struct serial *scb, serial_ttystate ttystate) 00487 { 00488 return scb->ops->copy_tty_state (scb, ttystate); 00489 } 00490 00491 int 00492 serial_set_tty_state (struct serial *scb, serial_ttystate ttystate) 00493 { 00494 return scb->ops->set_tty_state (scb, ttystate); 00495 } 00496 00497 void 00498 serial_print_tty_state (struct serial *scb, 00499 serial_ttystate ttystate, 00500 struct ui_file *stream) 00501 { 00502 scb->ops->print_tty_state (scb, ttystate, stream); 00503 } 00504 00505 int 00506 serial_noflush_set_tty_state (struct serial *scb, 00507 serial_ttystate new_ttystate, 00508 serial_ttystate old_ttystate) 00509 { 00510 return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate); 00511 } 00512 00513 int 00514 serial_setbaudrate (struct serial *scb, int rate) 00515 { 00516 return scb->ops->setbaudrate (scb, rate); 00517 } 00518 00519 int 00520 serial_setstopbits (struct serial *scb, int num) 00521 { 00522 return scb->ops->setstopbits (scb, num); 00523 } 00524 00525 int 00526 serial_can_async_p (struct serial *scb) 00527 { 00528 return (scb->ops->async != NULL); 00529 } 00530 00531 int 00532 serial_is_async_p (struct serial *scb) 00533 { 00534 return (scb->ops->async != NULL) && (scb->async_handler != NULL); 00535 } 00536 00537 void 00538 serial_async (struct serial *scb, 00539 serial_event_ftype *handler, 00540 void *context) 00541 { 00542 int changed = ((scb->async_handler == NULL) != (handler == NULL)); 00543 00544 scb->async_handler = handler; 00545 scb->async_context = context; 00546 /* Only change mode if there is a need. */ 00547 if (changed) 00548 scb->ops->async (scb, handler != NULL); 00549 } 00550 00551 void 00552 serial_debug (struct serial *scb, int debug_p) 00553 { 00554 scb->debug_p = debug_p; 00555 } 00556 00557 int 00558 serial_debug_p (struct serial *scb) 00559 { 00560 return scb->debug_p || global_serial_debug_p; 00561 } 00562 00563 #ifdef USE_WIN32API 00564 void 00565 serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) 00566 { 00567 if (scb->ops->wait_handle) 00568 scb->ops->wait_handle (scb, read, except); 00569 else 00570 { 00571 *read = (HANDLE) _get_osfhandle (scb->fd); 00572 *except = NULL; 00573 } 00574 } 00575 00576 void 00577 serial_done_wait_handle (struct serial *scb) 00578 { 00579 if (scb->ops->done_wait_handle) 00580 scb->ops->done_wait_handle (scb); 00581 } 00582 #endif 00583 00584 int 00585 serial_pipe (struct serial *scbs[2]) 00586 { 00587 struct serial_ops *ops; 00588 int fildes[2]; 00589 00590 ops = serial_interface_lookup ("pipe"); 00591 if (!ops) 00592 { 00593 errno = ENOSYS; 00594 return -1; 00595 } 00596 00597 if (gdb_pipe (fildes) == -1) 00598 return -1; 00599 00600 scbs[0] = serial_fdopen_ops (fildes[0], ops); 00601 scbs[1] = serial_fdopen_ops (fildes[1], ops); 00602 return 0; 00603 } 00604 00605 /* Serial set/show framework. */ 00606 00607 static struct cmd_list_element *serial_set_cmdlist; 00608 static struct cmd_list_element *serial_show_cmdlist; 00609 00610 static void 00611 serial_set_cmd (char *args, int from_tty) 00612 { 00613 printf_unfiltered ("\"set serial\" must be followed " 00614 "by the name of a command.\n"); 00615 help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout); 00616 } 00617 00618 static void 00619 serial_show_cmd (char *args, int from_tty) 00620 { 00621 cmd_show_list (serial_show_cmdlist, from_tty, ""); 00622 } 00623 00624 /* Baud rate specified for talking to serial target systems. Default 00625 is left as -1, so targets can choose their own defaults. */ 00626 /* FIXME: This means that "show serial baud" and gr_files_info can 00627 print -1 or (unsigned int)-1. This is a Bad User Interface. */ 00628 00629 int baud_rate = -1; 00630 00631 static void 00632 serial_baud_show_cmd (struct ui_file *file, int from_tty, 00633 struct cmd_list_element *c, const char *value) 00634 { 00635 fprintf_filtered (file, _("Baud rate for remote serial I/O is %s.\n"), 00636 value); 00637 } 00638 00639 void 00640 _initialize_serial (void) 00641 { 00642 #if 0 00643 add_com ("connect", class_obscure, connect_command, _("\ 00644 Connect the terminal directly up to the command monitor.\n\ 00645 Use <CR>~. or <CR>~^D to break out.")); 00646 #endif /* 0 */ 00647 00648 add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\ 00649 Set default serial/parallel port configuration."), 00650 &serial_set_cmdlist, "set serial ", 00651 0/*allow-unknown*/, 00652 &setlist); 00653 00654 add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\ 00655 Show default serial/parallel port configuration."), 00656 &serial_show_cmdlist, "show serial ", 00657 0/*allow-unknown*/, 00658 &showlist); 00659 00660 /* If target is open when baud changes, it doesn't take effect until 00661 the next open (I think, not sure). */ 00662 add_setshow_zinteger_cmd ("baud", no_class, &baud_rate, _("\ 00663 Set baud rate for remote serial I/O."), _("\ 00664 Show baud rate for remote serial I/O."), _("\ 00665 This value is used to set the speed of the serial port when debugging\n\ 00666 using remote targets."), 00667 NULL, 00668 serial_baud_show_cmd, 00669 &serial_set_cmdlist, &serial_show_cmdlist); 00670 00671 /* The commands "set/show serial baud" used to have a different name. 00672 Add aliases to those names to facilitate the transition, and mark 00673 them as deprecated, in order to make users aware of the fact that 00674 the command names have been changed. */ 00675 { 00676 const char *cmd_name; 00677 struct cmd_list_element *cmd; 00678 00679 /* FIXME: There is a limitation in the deprecation mechanism, 00680 and the warning ends up not being displayed for prefixed 00681 aliases. So use a real command instead of an alias. */ 00682 add_setshow_zinteger_cmd ("remotebaud", class_alias, &baud_rate, _("\ 00683 Set baud rate for remote serial I/O."), _("\ 00684 Show baud rate for remote serial I/O."), _("\ 00685 This value is used to set the speed of the serial port when debugging\n\ 00686 using remote targets."), 00687 NULL, 00688 serial_baud_show_cmd, 00689 &setlist, &showlist); 00690 cmd_name = "remotebaud"; 00691 cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1); 00692 deprecate_cmd (cmd, "set serial baud"); 00693 cmd_name 00694 = "remotebaud"; /* needed because lookup_cmd updates the pointer */ 00695 cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1); 00696 deprecate_cmd (cmd, "show serial baud"); 00697 } 00698 00699 add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\ 00700 Set filename for remote session recording."), _("\ 00701 Show filename for remote session recording."), _("\ 00702 This file is used to record the remote session for future playback\n\ 00703 by gdbserver."), 00704 NULL, 00705 NULL, /* FIXME: i18n: */ 00706 &setlist, &showlist); 00707 00708 add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums, 00709 &serial_logbase, _("\ 00710 Set numerical base for remote session logging"), _("\ 00711 Show numerical base for remote session logging"), NULL, 00712 NULL, 00713 NULL, /* FIXME: i18n: */ 00714 &setlist, &showlist); 00715 00716 add_setshow_zuinteger_cmd ("serial", class_maintenance, 00717 &global_serial_debug_p, _("\ 00718 Set serial debugging."), _("\ 00719 Show serial debugging."), _("\ 00720 When non-zero, serial port debugging is enabled."), 00721 NULL, 00722 NULL, /* FIXME: i18n: */ 00723 &setdebuglist, &showdebuglist); 00724 }