Go to file
Sergio Durigan Junior 7d7571f0c1 Adjust i386 registers on SystemTap probes' arguments (PR breakpoints/24541)
This bug has been reported on PR breakpoints/24541, but it is possible
to reproduce it easily by running:

  make check-gdb TESTS=gdb.base/stap-probe.exp RUNTESTFLAGS='--target_board unix/-m32'

The underlying cause is kind of complex, and involves decisions made
by GCC and the sys/sdt.h header file about how to represent a probe
argument that lives in a register in 32-bit programs.  I'll use
Andrew's example on the bug to illustrate the problem.

libstdc++ has a probe named "throw" with two arguments.  On i386, the
probe is:

  stapsdt              0x00000028       NT_STAPSDT (SystemTap probe descriptors)
    Provider: libstdcxx
    Name: throw
    Location: 0x00072c96, Base: 0x00133d64, Semaphore: 0x00000000
    Arguments: 4@%si 4@%di

I.e., the first argument is an unsigned 32-bit value (represented by
the "4@") that lives on %si, and the second argument is an unsigned
32-bit value that lives on %di.  Note the discrepancy between the
argument size reported by the probe (32-bit) and the register size
being used to store the value (16-bit).

However, if you take a look at the disassemble of a program that uses
this probe, you will see:

    00072c80 <__cxa_throw@@CXXABI_1.3>:
       72c80:       57                      push   %edi
       72c81:       56                      push   %esi
       72c82:       53                      push   %ebx
       72c83:       8b 74 24 10             mov    0x10(%esp),%esi
       72c87:       e8 74 bf ff ff          call   6ec00 <__cxa_finalize@plt+0x980>
       72c8c:       81 c3 74 e3 10 00       add    $0x10e374,%ebx
       72c92:       8b 7c 24 14             mov    0x14(%esp),%edi
       72c96:       90                      nop                      <----------------- PROBE IS HERE
       72c97:       e8 d4 a2 ff ff          call   6cf70 <__cxa_get_globals@plt>
       72c9c:       83 40 04 01             addl   $0x1,0x4(%eax)
       72ca0:       83 ec 04                sub    $0x4,%esp
       72ca3:       ff 74 24 1c             pushl  0x1c(%esp)
       72ca7:       57                      push   %edi
       72ca8:       56                      push   %esi
       72ca9:       e8 62 a3 ff ff          call   6d010 <__cxa_init_primary_exception@plt>
       72cae:       8d 70 40                lea    0x40(%eax),%esi
       72cb1:       c7 00 01 00 00 00       movl   $0x1,(%eax)
       72cb7:       89 34 24                mov    %esi,(%esp)
       72cba:       e8 61 96 ff ff          call   6c320 <_Unwind_RaiseException@plt>
       72cbf:       89 34 24                mov    %esi,(%esp)
       72cc2:       e8 c9 84 ff ff          call   6b190 <__cxa_begin_catch@plt>
       72cc7:       e8 d4 b3 ff ff          call   6e0a0 <_ZSt9terminatev@plt>
       72ccc:       66 90                   xchg   %ax,%ax
       72cce:       66 90                   xchg   %ax,%ax

Note how the program is actually using %edi, and not %di, to store the
second argument.  This is the problem here.

GDB will basically read the probe argument, then read the contents of
%di, and then cast this value to uint32_t, which causes the wrong
value to be obtained.  In the gdb.base/stap-probe.exp case, this makes
GDB read the wrong memory location, and not be able to display a test
string.  In Andrew's example, this causes GDB to actually stop at a
"catch throw" when it should actually have *not* stopped.

After some discussion with Frank Eigler and Jakub Jelinek, it was
decided that this bug should be fixed on the client side (i.e., the
program that actually reads the probes), and this is why I'm proposing
this patch.

The idea is simple: we will have a gdbarch method, which, for now, is
only used by i386.  The generic code that deals with register operands
on gdb/stap-probe.c will call this method if it exists, passing the
current parse information, the register name and its number.

The i386 method will then verify if the register size is greater or
equal than the size reported by the stap probe (the "4@" part).  If it
is, we're fine.  Otherwise, it will check if we're dealing with any of
the "extendable" registers (like ax, bx, si, di, sp, etc.).  If we
are, it will change the register name to include the "e" prefix.

I have tested the patch here in many scenarios, and it fixes Andrew's
bug and also the regressions I mentioned before, on
gdb.base/stap-probe.exp.  No regressions where found on other tests.

Comments?

gdb/ChangeLog:
2019-06-27  Sergio Durigan Junior  <sergiodj@redhat.com>

	PR breakpoints/24541
	* gdbarch.c: Regenerate.
	* gdbarch.h: Regenerate.
	* gdbarch.sh: Add 'stap_adjust_register'.
	* i386-tdep.c: Include '<unordered_set>'.
	(i386_stap_adjust_register): New function.
	(i386_elf_init_abi): Register 'i386_stap_adjust_register'.
	* stap-probe.c (stap_parse_register_operand): Call
	'gdbarch_stap_adjust_register'.
2019-06-28 16:28:21 -04:00
bfd Prevent attempts to allocate excessive amounts of memory when parsing corrupt ELF files. 2019-06-28 15:30:43 +01:00
binutils Prevent attempts to allocate excessive amounts of memory when parsing corrupt ELF files. 2019-06-28 15:30:43 +01:00
config Add markers for 2.32 branch to NEWS and ChangeLog files. 2019-01-19 15:55:50 +00:00
contrib Update dg-extract-results.* from gcc 2018-08-06 16:05:16 +02:00
cpu cpu/or1k: Update fpu compare symbols to imply set flag 2019-06-13 06:16:19 +09:00
elfcpp [GOLD] R_PPC64_REL16_HIGH relocs 2019-06-28 10:17:08 +09:30
etc Update year range in copyright notice of binutils files 2019-01-01 22:06:53 +10:30
gas i386: Check vector length for scatter/gather prefetch instructions 2019-06-27 13:39:32 -07:00
gdb Adjust i386 registers on SystemTap probes' arguments (PR breakpoints/24541) 2019-06-28 16:28:21 -04:00
gnulib Fix gnulib/update-gnulib.sh 2019-06-21 13:23:59 +01:00
gold [GOLD] PowerPC tweak relnum tests 2019-06-28 10:18:03 +09:30
gprof Correct the alpha sorting of the short options in the usage description of the gprof program. 2019-05-20 17:17:24 +01:00
include libctf: endianness fixes 2019-06-21 13:04:02 +01:00
intl Change version to 2.32.51 and regenerate configure and pot files. 2019-01-19 16:51:42 +00:00
ld PowerPC notoc call stub tests 2019-06-28 10:16:17 +09:30
libctf libctf: fix ctf_open endianness problems with raw CTF files 2019-06-21 13:04:02 +01:00
libdecnumber Merge config/ changes from GCC. 2018-10-31 17:16:41 +00:00
libiberty Pull in patch for libiberty that fixes a stack exhaustion bug when demangling a pathalogically constructed mangled name. 2019-04-10 15:49:36 +01:00
opcodes i386: Check vector length for scatter/gather prefetch instructions 2019-06-27 13:39:32 -07:00
readline config.guess,config.sub: synchronize with config project master sources 2019-05-23 18:19:56 +02:00
sim sim/testsuite/or1k: Add tests for unordered compares 2019-06-13 21:27:10 +09:00
texinfo
zlib Merge config/ changes from GCC. 2018-10-31 17:16:41 +00:00
.cvsignore
.gitattributes
.gitignore
ar-lib Bump to autoconf 2.69 and automake 1.15.1 2018-06-19 16:55:06 -04:00
ChangeLog Add gnulib to gdb release tarball 2019-06-21 15:20:34 +02:00
compile
config-ml.in
config.guess config.guess,config.sub: synchronize with config project master sources 2019-05-23 18:19:56 +02:00
config.rpath
config.sub config.guess,config.sub: synchronize with config project master sources 2019-05-23 18:19:56 +02:00
configure Move gnulib to top level 2019-06-14 12:40:02 -06:00
configure.ac Move gnulib to top level 2019-06-14 12:40:02 -06:00
COPYING
COPYING3
COPYING3.LIB
COPYING.LIB
COPYING.LIBGLOSS
COPYING.NEWLIB
depcomp
djunpack.bat
install-sh
libtool.m4 Bump to autoconf 2.69 and automake 1.15.1 2018-06-19 16:55:06 -04:00
lt~obsolete.m4
ltgcc.m4
ltmain.sh
ltoptions.m4
ltsugar.m4
ltversion.m4
MAINTAINERS Move gnulib to top level 2019-06-14 12:40:02 -06:00
Makefile.def Move gnulib to top level 2019-06-14 12:40:02 -06:00
Makefile.in Move gnulib to top level 2019-06-14 12:40:02 -06:00
Makefile.tpl Revert "Sync top level files with versions from gcc." 2019-05-30 11:17:19 +01:00
makefile.vms
missing
mkdep
mkinstalldirs
move-if-change
multilib.am Merge autoconf / automake update changes from GCC. 2018-10-31 17:10:56 +00:00
README
README-maintainer-mode Bump to autoconf 2.69 and automake 1.15.1 2018-06-19 16:55:06 -04:00
setup.com
src-release.sh Add gnulib to gdb release tarball 2019-06-21 15:20:34 +02:00
symlink-tree
test-driver Bump to autoconf 2.69 and automake 1.15.1 2018-06-19 16:55:06 -04:00
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.