binutils-gdb/gdbserver/config.in
Simon Marchi 1eb3991427 gdb, gdbserver: remove configure check for fs_base/gs_base in user_regs_struct
I recently stumbled on this code mentioning Linux kernel 2.6.25, and
thought it could be time for some spring cleaning (newer GDBs probably
don't need to supports 12-year old kernels).  I then found that the
"legacy" case is probably broken anyway, which gives an even better
motivation for its removal.

In short, this patch removes the configure checks that check if
user_regs_struct contains the fs_base/gs_base fields and adjusts all
uses of the HAVE_STRUCT_USER_REGS_STRUCT_{FS,GS}_BASE macros.  The
longer explanation/rationale follows.

Apparently, Linux kernels since 2.6.25 (that's from 2008) have been
reliably providing fs_base and gs_base as part of user_regs_struct.
Commit df5d438e33d7 in the Linux kernel [1] seems related.  This means
that we can get these values by reading registers with PTRACE_GETREGS.
Previously, these values were obtained using a separate
PTRACE_ARCH_PRCTL ptrace call.

First, I'm not even sure the configure check was really right in the
first place.

The user_regs_struct used by GDB comes from
/usr/include/x86_64-linux-gnu/sys/user.h (or equivalent on other
distros) and is provided by glibc.  glibc has had the fs_base/gs_base
fields in there for a very long time, at least since this commit from
2001 [2].  The Linux kernel also has its version of user_regs_struct,
which I think was exported to user-space at some point.  It included the
fs_base/gs_base fields since at least this 2002 commit [3].  In any
case, my conclusion is that the fields were there long before the
aforementioned Linux kernel commit.  The kernel commit didn't add these
fields, it only made sure that they have reliable values when obtained
with PTRACE_GETREGS.

So, checking for the presence of the fs_base/gs_base fields in struct
user_regs_struct doesn't sound like a good way of knowing if we can
reliably get the fs_base/gs_base values from PTRACE_GETREGS.  My guess
is that if we were using that strategy on a < 2.6.25 kernel, things
would not work correctly:

- configure would find that the user_regs_struct has the fs_base/gs_base
  fields (which are probided by glibc anyway)
- we would be reading the fs_base/gs_base values using PTRACE_GETREGS,
  for which the kernel would provide unreliable values

Second, I have tried to see how things worked by forcing GDB to not use
fs_base/gs_base from PTRACE_GETREGS (forcing it to use the "legacy"
code, by configuring with

  ac_cv_member_struct_user_regs_struct_gs_base=no ac_cv_member_struct_user_regs_struct_fs_base=no

Doing so breaks writing registers back to the inferior.  For example,
calling an inferior functions gives an internal error:

    (gdb) p malloc(10)
    /home/smarchi/src/binutils-gdb/gdb/i387-tdep.c:1408: internal-error: invalid i387 regnum 152

The relevant last frames where this error happens are:

    #8  0x0000563123d262fc in internal_error (file=0x563123e93fd8 "/home/smarchi/src/binutils-gdb/gdb/i387-tdep.c", line=1408, fmt=0x563123e94482 "invalid i387 regnum %d") at /home/smarchi/src/binutils-gdb/gdbsupport/errors.cc:55
    #9  0x0000563123047d0d in i387_collect_xsave (regcache=0x5631269453f0, regnum=152, xsave=0x7ffd38402a20, gcore=0) at /home/smarchi/src/binutils-gdb/gdb/i387-tdep.c:1408
    #10 0x0000563122c69e8a in amd64_collect_xsave (regcache=0x5631269453f0, regnum=152, xsave=0x7ffd38402a20, gcore=0) at /home/smarchi/src/binutils-gdb/gdb/amd64-tdep.c:3448
    #11 0x0000563122c5e94c in amd64_linux_nat_target::store_registers (this=0x56312515fd10 <the_amd64_linux_nat_target>, regcache=0x5631269453f0, regnum=152) at /home/smarchi/src/binutils-gdb/gdb/amd64-linux-nat.c:335
    #12 0x00005631234c8c80 in target_store_registers (regcache=0x5631269453f0, regno=152) at /home/smarchi/src/binutils-gdb/gdb/target.c:3485
    #13 0x00005631232e8df7 in regcache::raw_write (this=0x5631269453f0, regnum=152, buf=0x56312759e468 "@\225\372\367\377\177") at /home/smarchi/src/binutils-gdb/gdb/regcache.c:765
    #14 0x00005631232e8f0c in regcache::cooked_write (this=0x5631269453f0, regnum=152, buf=0x56312759e468 "@\225\372\367\377\177") at /home/smarchi/src/binutils-gdb/gdb/regcache.c:778
    #15 0x00005631232e75ec in regcache::restore (this=0x5631269453f0, src=0x5631275eb130) at /home/smarchi/src/binutils-gdb/gdb/regcache.c:283
    #16 0x0000563123083fc4 in infcall_suspend_state::restore (this=0x5631273ed930, gdbarch=0x56312718cf20, tp=0x5631270bca90, regcache=0x5631269453f0) at /home/smarchi/src/binutils-gdb/gdb/infrun.c:9103
    #17 0x0000563123081eed in restore_infcall_suspend_state (inf_state=0x5631273ed930) at /home/smarchi/src/binutils-gdb/gdb/infrun.c:9151

The problem seems to be that amd64_linux_nat_target::store_registers
calls amd64_native_gregset_supplies_p to know whether gregset provides
fs_base.  When !HAVE_STRUCT_USER_REGS_STRUCT_FS_BASE,
amd64_native_gregset_supplies_p returns false.  store_registers
therefore assumes that it must be an "xstate" register.  This is of
course wrong, and that leads to the failed assertion when
i387_collect_xsave doesn't recognize the register.

amd64_linux_nat_target::store_registers could probably be fixed to
handle this case, but I don't think it's worth it, given that it would
only be to support very old kernels.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=df5d438e33d7fc914ba9b6e0d6b019a8966c5fcc
[2] https://sourceware.org/git/?p=glibc.git;a=commit;h=c9cf6ddeebb7bb
[3] https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=88e4bc32686ebd0b1111a94f93eba2d334241f68

gdb/ChangeLog:

	* configure.ac: Remove check for fs_base/gs_base in
	user_regs_struct.
	* configure: Re-generate.
	* config.in: Re-generate.
	* amd64-nat.c (amd64_native_gregset_reg_offset): Adjust.
	* amd64-linux-nat.c (amd64_linux_nat_target::fetch_registers,
	amd64_linux_nat_target::store_registers, ps_get_thread_area, ): Adjust.

gdbserver/ChangeLog:

	* configure.ac: Remove check for fs_base/gs_base in
	user_regs_struct.
	* configure: Re-generate.
	* config.in: Re-generate.
	* linux-x86-low.cc (x86_64_regmap, x86_fill_gregset,
	x86_store_gregset): Adjust.
2020-04-27 10:47:50 -04:00

503 lines
13 KiB
Plaintext

/* config.in. Generated from configure.ac by autoheader. */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define to 1 if std::thread works. */
#undef CXX_STD_THREAD
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#undef ENABLE_NLS
/* Define if self-testing features should be enabled */
#undef GDB_SELF_TEST
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* define if the compiler supports basic C++11 syntax */
#undef HAVE_CXX11
/* Define to 1 if you have the declaration of `ADDR_NO_RANDOMIZE', and to 0 if
you don't. */
#undef HAVE_DECL_ADDR_NO_RANDOMIZE
/* Define to 1 if you have the declaration of `asprintf', and to 0 if you
don't. */
#undef HAVE_DECL_ASPRINTF
/* Define to 1 if you have the declaration of `basename(char *)', and to 0 if
you don't. */
#undef HAVE_DECL_BASENAME
/* Define to 1 if you have the declaration of `ffs', and to 0 if you don't. */
#undef HAVE_DECL_FFS
/* Define to 1 if you have the declaration of `perror', and to 0 if you don't.
*/
#undef HAVE_DECL_PERROR
/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
don't. */
#undef HAVE_DECL_SNPRINTF
/* Define to 1 if you have the declaration of `strstr', and to 0 if you don't.
*/
#undef HAVE_DECL_STRSTR
/* Define to 1 if you have the declaration of `strtol', and to 0 if you don't.
*/
#undef HAVE_DECL_STRTOL
/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
don't. */
#undef HAVE_DECL_STRTOLL
/* Define to 1 if you have the declaration of `strtoul', and to 0 if you
don't. */
#undef HAVE_DECL_STRTOUL
/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
don't. */
#undef HAVE_DECL_STRTOULL
/* Define to 1 if you have the declaration of `strverscmp', and to 0 if you
don't. */
#undef HAVE_DECL_STRVERSCMP
/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
don't. */
#undef HAVE_DECL_VASPRINTF
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
don't. */
#undef HAVE_DECL_VSNPRINTF
/* Define to 1 if you have the `dladdr' function. */
#undef HAVE_DLADDR
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if the system has the type `Elf32_auxv_t'. */
#undef HAVE_ELF32_AUXV_T
/* Define to 1 if the system has the type `Elf64_auxv_t'. */
#undef HAVE_ELF64_AUXV_T
/* Define if <sys/procfs.h> has elf_fpregset_t. */
#undef HAVE_ELF_FPREGSET_T
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `fdwalk' function. */
#undef HAVE_FDWALK
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define if <sys/procfs.h> has fpregset_t. */
#undef HAVE_FPREGSET_T
/* Define to 1 if you have the `getauxval' function. */
#undef HAVE_GETAUXVAL
/* Define to 1 if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define to 1 if you have the `getrlimit' function. */
#undef HAVE_GETRLIMIT
/* Define to 1 if you have the `getrusage' function. */
#undef HAVE_GETRUSAGE
/* Define if <sys/procfs.h> has gregset_t. */
#undef HAVE_GREGSET_T
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if your system has the kinfo_getfile function. */
#undef HAVE_KINFO_GETFILE
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
#undef HAVE_LANGINFO_CODESET
/* Define to 1 if you have the `dl' library (-ldl). */
#undef HAVE_LIBDL
/* Define if you have the ipt library. */
#undef HAVE_LIBIPT
/* Define if the target supports branch tracing. */
#undef HAVE_LINUX_BTRACE
/* Define to 1 if you have the <linux/elf.h> header file. */
#undef HAVE_LINUX_ELF_H
/* Define to 1 if you have the <linux/perf_event.h> header file. */
#undef HAVE_LINUX_PERF_EVENT_H
/* Define if the target supports register sets. */
#undef HAVE_LINUX_REGSETS
/* Define if the target supports PTRACE_PEEKUSR for register access. */
#undef HAVE_LINUX_USRREGS
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if the system has the type `long long'. */
#undef HAVE_LONG_LONG
/* Define if <thread_db.h> has lwpid_t. */
#undef HAVE_LWPID_T
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
/* Define if you support the personality syscall. */
#undef HAVE_PERSONALITY
/* Define to 1 if you have the `pipe' function. */
#undef HAVE_PIPE
/* Define to 1 if you have the `pipe2' function. */
#undef HAVE_PIPE2
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the <poll.h> header file. */
#undef HAVE_POLL_H
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
/* Define to 1 if you have the `pread64' function. */
#undef HAVE_PREAD64
/* Define if <sys/procfs.h> has prfpregset_t. */
#undef HAVE_PRFPREGSET_T
/* Define if <sys/procfs.h> has prgregset32_t. */
#undef HAVE_PRGREGSET32_T
/* Define if <sys/procfs.h> has prgregset_t. */
#undef HAVE_PRGREGSET_T
/* Define to 1 if you have the <proc_service.h> header file. */
#undef HAVE_PROC_SERVICE_H
/* Define if <thread_db.h> has psaddr_t. */
#undef HAVE_PSADDR_T
/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* Define to 1 if you have the `pthread_setname_np' function. */
#undef HAVE_PTHREAD_SETNAME_NP
/* Define to 1 if you have the `pthread_sigmask' function. */
#undef HAVE_PTHREAD_SIGMASK
/* Define to 1 if you have the `ptrace64' function. */
#undef HAVE_PTRACE64
/* Define if the target supports PTRACE_GETFPXREGS for extended register
access. */
#undef HAVE_PTRACE_GETFPXREGS
/* Define if the target supports PTRACE_GETREGS for register access. */
#undef HAVE_PTRACE_GETREGS
/* Define to 1 if you have the <ptrace.h> header file. */
#undef HAVE_PTRACE_H
/* Define to 1 if you have the `pt_insn_event' function. */
#undef HAVE_PT_INSN_EVENT
/* Define to 1 if you have the `pwrite' function. */
#undef HAVE_PWRITE
/* Define to 1 if you have the `sbrk' function. */
#undef HAVE_SBRK
/* Define to 1 if you have the `setns' function. */
#undef HAVE_SETNS
/* Define to 1 if you have the `setpgid' function. */
#undef HAVE_SETPGID
/* Define to 1 if you have the `setpgrp' function. */
#undef HAVE_SETPGRP
/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION
/* Define to 1 if you have the `sigaltstack' function. */
#undef HAVE_SIGALTSTACK
/* Define to 1 if you have the <signal.h> header file. */
#undef HAVE_SIGNAL_H
/* Define to 1 if you have the `sigprocmask' function. */
#undef HAVE_SIGPROCMASK
/* Define if sigsetjmp is available. */
#undef HAVE_SIGSETJMP
/* Define to 1 if you have the `socketpair' function. */
#undef HAVE_SOCKETPAIR
/* Define to 1 if the system has the type `socklen_t'. */
#undef HAVE_SOCKLEN_T
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if `enabled' is a member of `struct pt_insn'. */
#undef HAVE_STRUCT_PT_INSN_ENABLED
/* Define to 1 if `resynced' is a member of `struct pt_insn'. */
#undef HAVE_STRUCT_PT_INSN_RESYNCED
/* Define to 1 if `st_blksize' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLKSIZE
/* Define to 1 if `st_blocks' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLOCKS
/* Define to 1 if the target supports __sync_*_compare_and_swap */
#undef HAVE_SYNC_BUILTINS
/* Define to 1 if you have the <sys/file.h> header file. */
#undef HAVE_SYS_FILE_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/poll.h> header file. */
#undef HAVE_SYS_POLL_H
/* Define to 1 if you have the <sys/procfs.h> header file. */
#undef HAVE_SYS_PROCFS_H
/* Define to 1 if you have the <sys/ptrace.h> header file. */
#undef HAVE_SYS_PTRACE_H
/* Define to 1 if you have the <sys/reg.h> header file. */
#undef HAVE_SYS_REG_H
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define if TD_VERSION is available. */
#undef HAVE_TD_VERSION
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the <thread_db.h> header file. */
#undef HAVE_THREAD_DB_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if UST is available */
#undef HAVE_UST
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if you have the <wait.h> header file. */
#undef HAVE_WAIT_H
/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Additional package description */
#undef PKGVERSION
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define to the type of arg 1 for ptrace. */
#undef PTRACE_TYPE_ARG1
/* Define to the type of arg 3 for ptrace. */
#undef PTRACE_TYPE_ARG3
/* Define to the type of arg 4 for ptrace. */
#undef PTRACE_TYPE_ARG4
/* Define to the type of arg 5 for ptrace. */
#undef PTRACE_TYPE_ARG5
/* Define as the return type of ptrace. */
#undef PTRACE_TYPE_RET
/* Bug reporting address */
#undef REPORT_BUGS_TO
/* The size of `long long', as computed by sizeof. */
#undef SIZEOF_LONG_LONG
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if we should use libthread_db directly. */
#undef USE_LIBTHREAD_DB_DIRECTLY
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Define if we should use libthread_db. */
#undef USE_THREAD_DB
/* Define if we should use the Windows API, instead of the POSIX API. On
Windows, we use the Windows API when building for MinGW, but the POSIX API
when building for Cygwin. */
#undef USE_WIN32API
/* Define if an XML target description is available. */
#undef USE_XML
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork