gdb: unix: allow to use custom baud rate

This commit is contained in:
Alexey Lapshin
2024-09-10 21:04:41 +07:00
parent fa01c85e7b
commit 7e20166848
4 changed files with 165 additions and 6 deletions

View File

@@ -93,6 +93,9 @@
/* Define if amd-dbgapi is being linked in. */
#undef HAVE_AMD_DBGAPI
/* Define to 1 if you have the <asm/termios.h> header file. */
#undef HAVE_ASM_TERMIOS_H
/* Define to 1 if you have the `btowc' function. */
#undef HAVE_BTOWC
@@ -241,6 +244,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <IOKit/serial/ioss.h> header file. */
#undef HAVE_IOKIT_SERIAL_IOSS_H
/* Define to 1 if you have the `kinfo_getfile' function. */
#undef HAVE_KINFO_GETFILE

6
gdb/configure vendored
View File

@@ -11504,7 +11504,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 11503 "configure"
#line 11507 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11610,7 +11610,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 11609 "configure"
#line 11613 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -29228,6 +29228,8 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi
for ac_header in \
asm/termios.h \
IOKit/serial/ioss.h \
machine/reg.h \
nlist.h \
ptrace.h \

View File

@@ -1332,6 +1332,8 @@ AC_SUBST(SRCHIGH_CFLAGS)
AC_HEADER_STDC
AC_CHECK_HEADERS([ \
asm/termios.h \
IOKit/serial/ioss.h \
machine/reg.h \
nlist.h \
ptrace.h \

View File

@@ -30,9 +30,30 @@
#include "gdbsupport/gdb_select.h"
#include "cli/cli-cmds.h"
#include "gdbsupport/filestuff.h"
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#if HAVE_IOKIT_SERIAL_IOSS_H
#include <IOKit/serial/ioss.h>
#endif
#if HAVE_ASM_TERMIOS_H
/* Workaround to resolve conflicting declarations of termios
* in <asm/termbits.h> and <termios.h>. */
#define termios asmtermios
#include <asm/termbits.h>
#undef termios
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#else
#error "termios.h must be present to control serial port"
#endif
#include "gdbsupport/scoped_ignore_sigttou.h"
#if defined(HAVE_SYS_IOCTL_H) && (defined(BOTHER) || defined(IOSSIOSPEED))
#define HAVE_CUSTOM_BAUDRATE_SUPPORT 1
#endif
struct hardwire_ttystate
{
struct termios termios;
@@ -289,10 +310,28 @@ baudtab[] =
4800, B4800
}
,
#ifdef B7200
{
7200, B7200
}
,
#endif
{
9600, B9600
}
,
#ifdef B14400
{
14400, B14400
}
,
#endif
#ifdef B28800
{
28800, B28800
}
,
#endif
{
19200, B19200
}
@@ -307,6 +346,12 @@ baudtab[] =
}
,
#endif
#ifdef B76800
{
76800, B76800
}
,
#endif
#ifdef B115200
{
115200, B115200
@@ -412,6 +457,7 @@ rate_to_code (int rate)
/* check if it is in between valid values. */
if (rate < baudtab[i].rate)
{
#if !HAVE_CUSTOM_BAUDRATE_SUPPORT
if (i)
{
error (_("Invalid baud rate %d. "
@@ -423,21 +469,29 @@ rate_to_code (int rate)
error (_("Invalid baud rate %d. Minimum value is %d."),
rate, baudtab[0].rate);
}
#else
return -1;
#endif
}
}
}
#if !HAVE_CUSTOM_BAUDRATE_SUPPORT
/* The requested speed was too large. */
error (_("Invalid baud rate %d. Maximum value is %d."),
rate, baudtab[i - 1].rate);
#else
return -1;
#endif
}
/* Set baud rate using B_code from termios.h. */
static void
hardwire_setbaudrate (struct serial *scb, int rate)
set_baudcode_baudrate (struct serial *scb, int baud_code)
{
struct hardwire_ttystate state;
int baud_code = rate_to_code (rate);
if (get_tty_state (scb, &state))
perror_with_name ("could not get tty state");
@@ -448,6 +502,101 @@ hardwire_setbaudrate (struct serial *scb, int rate)
perror_with_name ("could not set tty state");
}
#if HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(BOTHER)
/* Set a custom baud rate using the termios BOTHER. */
static void
set_custom_baudrate_linux (int fd, int rate)
{
#ifdef TCGETS2
struct termios2 tio;
const unsigned long req_get = TCGETS2;
const unsigned long req_set = TCSETS2;
#else
struct termios tio;
const unsigned long req_get = TCGETS;
const unsigned long req_set = TCSETS;
#endif
if (ioctl (fd, req_get, &tio) < 0)
{
perror_with_name ("Can not get current baud rate");
}
/* Clear the current output baud rate and fill a new value */
tio.c_cflag &= ~CBAUD;
tio.c_cflag |= BOTHER;
tio.c_ospeed = rate;
/* Clear the current input baud rate and fill a new value */
tio.c_cflag &= ~(CBAUD << IBSHIFT);
tio.c_cflag |= BOTHER << IBSHIFT;
tio.c_ispeed = rate;
if (ioctl (fd, req_set, &tio) < 0)
{
perror_with_name ("Can not set custom baud rate");
}
}
#elif HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(IOSSIOSPEED)
/* Set a custom baud rate using the IOSSIOSPEED ioctl call. */
static void
set_custom_baudrate_darwin (int fd, int rate)
{
if (ioctl (fd, IOSSIOSPEED, &rate) < 0)
{
error ("Can not set custom baud rate");
}
}
#endif /* HAVE_CUSTOM_BAUDRATE_SUPPORT
&& (defined(BOTHER) || defined(IOSSIOSPEED)) */
#if HAVE_CUSTOM_BAUDRATE_SUPPORT
/* Set a baud rate that differs from the OS B_codes.
* This is possible if one of the following macros is available:
* - BOTHER (Linux).
* - IOSSIOSPEED (Darwin). */
static void
set_custom_baudrate (int fd, int rate)
{
#if defined(BOTHER)
set_custom_baudrate_linux (fd, rate);
#elif defined(IOSSIOSPEED)
set_custom_baudrate_darwin (fd, rate);
#endif
}
#endif /* HAVE_CUSTOM_BAUDRATE_SUPPORT */
/* Set the baud rate for the serial communication. */
static void
hardwire_setbaudrate (struct serial *scb, int rate)
{
int baud_code = rate_to_code (rate);
if (baud_code < 0)
{
#if HAVE_CUSTOM_BAUDRATE_SUPPORT
set_custom_baudrate (scb->fd, rate);
#else
/* An error should already have been thrown by rate_to_code().
* Add an additional error in case execution somehow reaches this line. */
perror_with_name ("Serial baud rate was not found in B_codes");
#endif
}
else
set_baudcode_baudrate (scb, baud_code);
}
static int
hardwire_setstopbits (struct serial *scb, int num)
{