Go to file
Andrew Burgess d51096abee gdb/i386: fix tdesc rejection issue for targets without PTRACE_GETREGSET
After the x86 target description changes that I committed recently,
the first commit in the series being:

  commit 8a29222b85
  Date:   Sat Jan 27 10:40:35 2024 +0000

      gdb/gdbserver: share I386_LINUX_XSAVE_XCR0_OFFSET definition

and the last commit in the series being:

  commit 646d754d14
  Author: Andrew Burgess <aburgess@redhat.com>
  Date:   Tue Jan 30 15:37:23 2024 +0000

      gdb/gdbserver: share x86/linux tdesc caching

The sourceware buildbot highlighted a regression on i386.  On the GDB
side we'd see this:

  Remote debugging using :54321
  warning: Architecture rejected target-supplied description
  Remote connection closed
  (gdb)

while on the gdbserver side we'd see this:

  $ ./gdbserver/gdbserver --once :54321 ~/empty
  Process /srv/aburgess/empty created; pid = 31406
  Listening on port 54321
  Remote debugging from host ::1, port 39488
  ../../src/gdbserver/regcache.cc:272: A problem internal to GDBserver has been detected.
  Unknown register st0 requested
  Aborted (core dumped)

When I tried to reproduce this regression on my local i386 VM the
issue would not reproduce.

I eventually tracked the problem down to x86_linux_tdesc_for_tid in
gdb/nat/x86-linux-tdesc.c.  In this function we have this line:

  /* Check if PTRACE_GETREGSET works.  */
  if (ptrace (PTRACE_GETREGSET, tid,
              (unsigned int) NT_X86_XSTATE, &iov) < 0)
    {
      ... handle failure ...
    }
  else
    {
      ... handle success ...
    }

The problem is that on my VM the PTRACE_GETREGSET feature is
supported, while on sourceware's buildbot machine this feature is not
supported.

I did a quick search and it seems like the 'xsave' feature in
/proc/cpuinfo might be the indicator for whether PTRACE_GETREGSET is
supported or not, and indeed my machine has the 'xsave' feature while
the sourceware machine does not.

The point of divergence then is this ptrace call, on my machine the
call succeeds and we extract the xcr0 value from the iov vector, while
on the sourceware machine the ptrace call fails and we use a default
xcr0 value of 0.

This xcr0 value is then passed to i386_linux_read_description at the
end of x86_linux_tdesc_for_tid.

In gdb/arch/i386-linux-tdesc.c we find i386_linux_read_description
which does some caching but calls i386_create_target_description to
actually create the target descriptions when needed.  The xcr0 value
is masked to only the bits that are interesting, but given a value of
0 we'll just pass 0 through to i386_create_target_description.

In gdb/arch/i386.c we find i386_create_target_description which checks
the xcr0 bits and builds the target description.  What we can see is
that if no bits are set in the xcr0 value then no features will be
added to the created target description.  This featureless target
description is then transmitted back to GDB, which is then rejected
due to lack of essential core registers.

So, how did things work prior to the above commit series?  There are
three places of interest, on the GDB side there is
x86_linux_nat_target::read_description and
i386_linux_core_read_description.  Then on the gdbserver side there is
x86_linux_read_description.

All of these locations have a call to i386_linux_read_description
followed by a check if the return value was nullptr.  If we do get
back nullptr then we perform another call to
i386_linux_read_description with a default xcr0 value.

Looking in i386_linux_read_description we see a specific check for
xcr0 being 0 in which case we return nullptr.

And so, prior to the above series, if xcr0 was 0 due to
PTRACE_GETREGSET being unavailable we'd use a default xcr0 value.

After the above series this is no longer the case, the 'xcr0 == 0'
check has been removed from i386_linux_read_description and the
calling code is streamlined to remove the use of default xcr0 values.

The fix I propose here is to setup the default xcr0 value at the point
where we find that PTRACE_GETREGSET is unavailable.  The default value
used is X86_XSTATE_SSE_MASK.  This is the default used in
x86_linux_nat_target::read_description (for GDB) and in
x86_linux_read_description (for gdbserver).  The above commit series
already fixed i386_linux_core_read_description to ensure that the
correct default xcr0 value was used, this case is a little special in
that it uses different defaults depending on which sections are
present in the core file, so that case always needed to be handled
differently.

The choice of X86_XSTATE_SSE_MASK corresponds to the default used for
i386 before the above series was committed.  This mask includes the
X87 and SSE bits only, neither of these bits are checked for on amd64
or x32, so this default doesn't change the behaviour on these targets.

By setting the default xcr0 value at this early stage we ensure that
the cached xcr0 value on the gdbserver side is correct.  This is
critical as this cached xcr0 value is passed through to the in process
agent (IPA).  If we leave the cached xcr0 value as 0 and apply the
defaults later in the series we also have to encode the knowledge of
the default into the IPA, this just means we have the default encoded
in multiple locations, which seems like a bad idea.  The approach used
in this patch means the default is present in just one location.

This commit should fix the i386 regressions seen on the sourceware
buildbot.
2024-06-21 11:43:58 +01:00
bfd Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
binutils Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
config Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
contrib contrib: sync dg-extract-results.sh with GCC 2024-03-12 15:49:25 +00:00
cpu PR21739, Inconsistent diagnostics 2024-02-29 21:07:04 +10:30
elfcpp x86-64: Add R_X86_64_CODE_6_GOTTPOFF 2024-02-08 03:45:43 -08:00
etc Update year range in copyright notice of binutils files 2024-01-04 22:58:12 +10:30
gas Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
gdb gdb/i386: fix tdesc rejection issue for targets without PTRACE_GETREGSET 2024-06-21 11:43:58 +01:00
gdbserver Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
gdbsupport Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
gnulib autoupdate: replace obsolete macros AC_CONFIG_HEADER 2024-06-10 08:25:55 +09:30
gold Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
gprof Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
gprofng autoupdate: add square brackets around arguments of AC_INIT 2024-06-10 08:25:56 +09:30
include libctf, include: new functions for looking up enumerators 2024-06-18 13:20:32 +01:00
ld Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
libbacktrace autoupdate: regen after replacing obsolete macros 2024-06-10 08:25:56 +09:30
libctf Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
libdecnumber regen config 2023-08-12 10:27:57 +09:30
libiberty autoupdate: regen after replacing obsolete macros 2024-06-10 08:25:56 +09:30
libsframe autoupdate: add square brackets around arguments of AC_INIT 2024-06-10 08:25:56 +09:30
opcodes Revert "Remove LIBINTL_DEP" 2024-06-20 21:15:27 +09:30
readline autoupdate: add square brackets around arguments of AC_INIT 2024-06-10 08:25:56 +09:30
sim regen sim/frv files for copyright update 2024-06-10 08:25:56 +09:30
texinfo
zlib autoupdate: regen after replacing obsolete macros 2024-06-10 08:25:56 +09:30
.cvsignore
.editorconfig
.gitattributes binutils-gdb/git: highlight whitespace errors in source files 2022-07-25 14:35:41 +01:00
.gitignore .gitignore: ignore .vscode 2024-05-30 12:09:35 +01:00
.pre-commit-config.yaml gdb: bump black version to 24.4.2 2024-05-16 11:34:40 -04:00
ar-lib
ChangeLog .pre-commit-config.yaml: bump black hook to 24.3.0 2024-03-20 14:44:16 -04:00
compile
config-ml.in MSP430: Add -fno-exceptions multilib 2023-08-12 10:24:26 +09:30
config.guess Synchronize config.sub and config.guess with their upstream master versions. 2024-01-04 12:00:34 +00:00
config.rpath
config.sub Synchronize config.sub and config.guess with their upstream master versions. 2024-01-04 12:00:34 +00:00
configure autoupdate: regen after replacing obsolete macros 2024-06-10 08:25:56 +09:30
configure.ac autoupdate: replace old version of AC_INIT by the new one 2024-06-10 08:25:55 +09:30
COPYING
COPYING3
COPYING3.LIB
COPYING.LIB
COPYING.LIBGLOSS
COPYING.NEWLIB
depcomp
djunpack.bat
install-sh
libtool.m4 FDPIC: Handle arm*-*-uclinuxfdpiceabi in configure scripts 2023-08-12 10:25:06 +09:30
lt~obsolete.m4
ltgcc.m4
ltmain.sh Do not use HAVE_DOS_BASED_FILE_SYSTEM for Cygwin. 2023-08-12 10:25:06 +09:30
ltoptions.m4
ltsugar.m4
ltversion.m4
MAINTAINERS Fix compiling bfd/vms-lib.c for a 32-bit host. 2024-03-18 10:26:16 +00:00
Makefile.def Revert "Pass GUILE down to subdirectories" 2024-03-22 11:07:28 -06:00
Makefile.in Revert "Pass GUILE down to subdirectories" 2024-03-22 11:07:28 -06:00
Makefile.tpl Revert "Pass GUILE down to subdirectories" 2024-03-22 11:07:28 -06:00
makefile.vms
missing
mkdep
mkinstalldirs
move-if-change
multilib.am
README
README-maintainer-mode Note that at least dejagnu version 1.5.3 is required in order to be ale to run the testsuites. 2022-10-04 10:54:19 +01:00
SECURITY.txt Add a SECURITY.txt file describing the GNU Binutils' project's stance on security related bugs. 2023-04-20 16:52:11 +01:00
setup.com
src-release.sh src-release.sh: don't take untracked files into account in the uncommitted changes check 2024-06-10 12:40:06 +01:00
symlink-tree
test-driver
ylwrap

		   README for GNU development tools

This directory contains various GNU compilers, assemblers, linkers, 
debuggers, etc., plus their support routines, definitions, and documentation.

If you are receiving this as part of a GDB release, see the file gdb/README.
If with a binutils release, see binutils/README;  if with a libg++ release,
see libg++/README, etc.  That'll give you info about this
package -- supported targets, how to use it, how to report bugs, etc.

It is now possible to automatically configure and build a variety of
tools with one command.  To build all of the tools contained herein,
run the ``configure'' script here, e.g.:

	./configure 
	make

To install them (by default in /usr/local/bin, /usr/local/lib, etc),
then do:
	make install

(If the configure script can't determine your type of computer, give it
the name as an argument, for instance ``./configure sun4''.  You can
use the script ``config.sub'' to test whether a name is recognized; if
it is, config.sub translates it to a triplet specifying CPU, vendor,
and OS.)

If you have more than one compiler on your system, it is often best to
explicitly set CC in the environment before running configure, and to
also set CC when running make.  For example (assuming sh/bash/ksh):

	CC=gcc ./configure
	make

A similar example using csh:

	setenv CC gcc
	./configure
	make

Much of the code and documentation enclosed is copyright by
the Free Software Foundation, Inc.  See the file COPYING or
COPYING.LIB in the various directories, for a description of the
GNU General Public License terms under which you can copy the files.

REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info
on where and how to report problems.