Compare commits

...

6 Commits
master ... f27

Author SHA1 Message Date
Jan Kratochvil a85ad4966c Fix signal handlers regression (RH BZ 1542149, Pedro Alves). 2018-02-06 22:41:37 +01:00
Sergio Durigan Junior 259e224402 Add %patch directive to the commit below. (and bump version) 2018-01-25 14:33:21 -05:00
Sergio Durigan Junior 60f38d2ebd Applying the patch for last commit. 2018-01-25 14:28:45 -05:00
Sergio Durigan Junior 81b9cf010a Fix random 'FAIL: libstdc++-prettyprinters/80276.cc whatis p4' (GCC PR83906) (Pedro Alves). 2018-01-24 15:00:35 -05:00
Jan Kratochvil cc58fc0cba [rhel7] Fix C++ compiler compatibility. 2017-12-06 21:09:32 +01:00
Jan Kratochvil 081d76f3ce Backport upstream fix for Intel PKRU (Walfred Tedeschi).
Backport upstream fix AVX instr. single-stepping (RH BZ 1515209, Pedro Alves).
Fix snapgnulib bundle number.
2017-12-06 12:45:27 +01:00
5 changed files with 1037 additions and 3 deletions

View File

@ -0,0 +1,229 @@
From: Pedro Alves <palves at redhat dot com>
To: gdb-patches at sourceware dot org
Subject: [PATCH] Fix GCC PR83906 - [8 Regression] Random FAIL: libstdc++-prettyprinters/80276.cc whatis p4
Date: Wed, 24 Jan 2018 17:27:22 +0000
Message-Id: <20180124172722.31553-1-palves@redhat.com>
GCC PR83906 [1] is about a GCC/libstdc++ GDB/Python type printer
testcase failing randomly, as shown by running (in libstdc++'s
testsuite):
make check RUNTESTFLAGS=prettyprinters.exp=80276.cc
in a loop. Sometimes you get this:
FAIL: libstdc++-prettyprinters/80276.cc whatis p4
I.e., this:
type = std::unique_ptr<std::vector<std::unique_ptr<std::list<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >>[]>>[99]>
instead of this:
type = std::unique_ptr<std::vector<std::unique_ptr<std::list<std::string>[]>>[99]>
Jonathan Wakely tracked it on the printer side to this bit in
libstdc++'s type printer:
if self.type_obj == type_obj:
return strip_inline_namespaces(self.name)
This assumes the two types resolve to the same gdb.Type but some times
the comparison unexpectedly fails.
Running the testcase manually under Valgrind finds the problem in GDB:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
==6118== Conditional jump or move depends on uninitialised value(s)
==6118== at 0x4C35CB0: bcmp (vg_replace_strmem.c:1100)
==6118== by 0x6F773A: check_types_equal(type*, type*, VEC_type_equality_entry_d**) (gdbtypes.c:3515)
==6118== by 0x6F7B00: check_types_worklist(VEC_type_equality_entry_d**, bcache*) (gdbtypes.c:3618)
==6118== by 0x6F7C03: types_deeply_equal(type*, type*) (gdbtypes.c:3655)
==6118== by 0x4D5B06: typy_richcompare(_object*, _object*, int) (py-type.c:1007)
==6118== by 0x63D7E6C: PyObject_RichCompare (object.c:961)
==6118== by 0x646EAEC: PyEval_EvalFrameEx (ceval.c:4960)
==6118== by 0x646DC08: PyEval_EvalFrameEx (ceval.c:4519)
==6118== by 0x646DC08: PyEval_EvalFrameEx (ceval.c:4519)
==6118== by 0x646DC08: PyEval_EvalFrameEx (ceval.c:4519)
==6118== by 0x646DC08: PyEval_EvalFrameEx (ceval.c:4519)
==6118== by 0x646DC08: PyEval_EvalFrameEx (ceval.c:4519)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
That "bcmp" call is really a memcmp call in check_types_equal. The
problem is that gdb is memcmp'ing two objects that are equal in value:
(top-gdb) p *TYPE_RANGE_DATA (type1)
$1 = {low = {kind = PROP_CONST, data = {const_val = 0, baton = 0x0}}, high = {kind = PROP_CONST, data = {const_val = 15, baton = 0xf}}, flag_upper_bound_is_count = 0,
flag_bound_evaluated = 0}
(top-gdb) p *TYPE_RANGE_DATA (type2)
$2 = {low = {kind = PROP_CONST, data = {const_val = 0, baton = 0x0}}, high = {kind = PROP_CONST, data = {const_val = 15, baton = 0xf}}, flag_upper_bound_is_count = 0,
flag_bound_evaluated = 0}
but differ in padding. Notice the 4-byte hole:
(top-gdb) ptype /o range_bounds
/* offset | size */ type = struct range_bounds {
/* 0 | 16 */ struct dynamic_prop {
/* 0 | 4 */ dynamic_prop_kind kind;
/* XXX 4-byte hole */
/* 8 | 8 */ union dynamic_prop_data {
/* 8 */ LONGEST const_val;
/* 8 */ void *baton;
/* total size (bytes): 8 */
} data;
which is filled with garbage:
(top-gdb) x /40bx TYPE_RANGE_DATA (type1)
0x2fa7ea0: 0x01 0x00 0x00 0x00 0x43 0x01 0x00 0x00
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0x2fa7ea8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x2fa7eb0: 0x01 0x00 0x00 0x00 0xfe 0x7f 0x00 0x00
0x2fa7eb8: 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x2fa7ec0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(top-gdb) x /40bx TYPE_RANGE_DATA (type2)
0x20379b0: 0x01 0x00 0x00 0x00 0xfe 0x7f 0x00 0x00
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0x20379b8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x20379c0: 0x01 0x00 0x00 0x00 0xfe 0x7f 0x00 0x00
0x20379c8: 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x20379d0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
(top-gdb) p memcmp (TYPE_RANGE_DATA (type1), TYPE_RANGE_DATA (type2), sizeof (*TYPE_RANGE_DATA (type1)))
$3 = -187
In some cases objects of type range_bounds are memset when allocated,
but then their dynamic_prop low/high fields are copied over from some
template dynamic_prop object that wasn't memset. E.g.,
create_static_range_type's low/high locals are left with garbage in
the padding, and then that padding is copied over to the range_bounds
object's low/high fields.
At first, I considered making sure to always memset range_bounds
objects, thinking that maybe type objects are being put in some bcache
instance somewhere. But then I hacked bcache/bcache_full to poison
non-pod types, and made dynamic_prop a non-pod, and GDB still
compiled.
So given that, it seems safest to not assume padding will always be
memset, and instead treat them as regular value types, implementing
(in)equality operators and using those instead of memcmp.
This fixes the random FAILs in GCC's testcase.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83906
gdb/ChangeLog:
2018-01-24 Pedro Alves <palves@redhat.com>
GCC PR libstdc++/83906
* gdbtypes.c (operator==(const dynamic_prop &,
const dynamic_prop &)): New.
(operator==(const range_bounds &, const range_bounds &)): New.
(check_types_equal): Use them instead of memcmp.
* gdbtypes.h (operator==(const dynamic_prop &,
const dynamic_prop &)): Declare.
(operator!=(const dynamic_prop &, const dynamic_prop &)): Declare.
(operator==(const range_bounds &, const range_bounds &)): Declare.
(operator!=(const range_bounds &, const range_bounds &)): Declare.
---
gdb/gdbtypes.c | 41 +++++++++++++++++++++++++++++++++++++++--
gdb/gdbtypes.h | 20 ++++++++++++++++++++
2 files changed, 59 insertions(+), 2 deletions(-)
Index: gdb-8.0.1/gdb/gdbtypes.c
===================================================================
--- gdb-8.0.1.orig/gdb/gdbtypes.c
+++ gdb-8.0.1/gdb/gdbtypes.c
@@ -855,6 +855,44 @@ allocate_stub_method (struct type *type)
return mtype;
}
+/* See gdbtypes.h. */
+
+bool
+operator== (const dynamic_prop &l, const dynamic_prop &r)
+{
+ if (l.kind != r.kind)
+ return false;
+
+ switch (l.kind)
+ {
+ case PROP_UNDEFINED:
+ return true;
+ case PROP_CONST:
+ return l.data.const_val == r.data.const_val;
+ case PROP_ADDR_OFFSET:
+ case PROP_LOCEXPR:
+ case PROP_LOCLIST:
+ return l.data.baton == r.data.baton;
+ }
+
+ gdb_assert_not_reached ("unhandled dynamic_prop kind");
+}
+
+/* See gdbtypes.h. */
+
+bool
+operator== (const range_bounds &l, const range_bounds &r)
+{
+#define FIELD_EQ(FIELD) (l.FIELD == r.FIELD)
+
+ return (FIELD_EQ (low)
+ && FIELD_EQ (high)
+ && FIELD_EQ (flag_upper_bound_is_count)
+ && FIELD_EQ (flag_bound_evaluated));
+
+#undef FIELD_EQ
+}
+
/* Create a range type with a dynamic range from LOW_BOUND to
HIGH_BOUND, inclusive. See create_range_type for further details. */
@@ -3466,8 +3504,7 @@ check_types_equal (struct type *type1, s
if (TYPE_CODE (type1) == TYPE_CODE_RANGE)
{
- if (memcmp (TYPE_RANGE_DATA (type1), TYPE_RANGE_DATA (type2),
- sizeof (*TYPE_RANGE_DATA (type1))) != 0)
+ if (*TYPE_RANGE_DATA (type1) != *TYPE_RANGE_DATA (type2))
return 0;
}
else
Index: gdb-8.0.1/gdb/gdbtypes.h
===================================================================
--- gdb-8.0.1.orig/gdb/gdbtypes.h
+++ gdb-8.0.1/gdb/gdbtypes.h
@@ -408,6 +408,16 @@ struct dynamic_prop
union dynamic_prop_data data;
};
+/* Compare two dynamic_prop objects for equality. dynamic_prop
+ instances are equal iff they have the same type and storage. */
+extern bool operator== (const dynamic_prop &l, const dynamic_prop &r);
+
+/* Compare two dynamic_prop objects for inequality. */
+static inline bool operator!= (const dynamic_prop &l, const dynamic_prop &r)
+{
+ return !(l == r);
+}
+
/* * Define a type's dynamic property node kind. */
enum dynamic_prop_node_kind
{
@@ -568,6 +578,16 @@ struct range_bounds
int flag_bound_evaluated : 1;
};
+/* Compare two range_bounds objects for equality. Simply does
+ memberwise comparison. */
+extern bool operator== (const range_bounds &l, const range_bounds &r);
+
+/* Compare two range_bounds objects for inequality. */
+static inline bool operator!= (const range_bounds &l, const range_bounds &r)
+{
+ return !(l == r);
+}
+
union type_specific
{
/* * CPLUS_STUFF is for TYPE_CODE_STRUCT. It is initialized to

View File

@ -130,7 +130,7 @@ Index: gdb-8.0.1/gdb/symtab.h
struct program_space *pspace;
struct symtab *symtab;
+ struct symbol *symbol = NULL;
+ struct symbol *symbol;
struct obj_section *section;
/* Line number. Line numbers start at 1 and proceed through symtab->nlines.
0 is never a valid line number; it is used to indicate that line number

View File

@ -0,0 +1,320 @@
commit e379cee61f3890e535e995828e8846b020ef2a32
Author: Pedro Alves <palves@redhat.com>
Date: Fri Jan 5 18:26:18 2018 +0000
Fix regression: cannot start with LD_PRELOAD=libSegFault.so (PR gdb/18653#c7)
At https://sourceware.org/bugzilla/show_bug.cgi?id=18653#c7, Andrew
reports that the fix for PR gdb/18653 made GDB useless if you preload
libSegFault.so, because GDB internal-errors on startup:
$ LD_PRELOAD=libSegFault.so gdb
src/gdb/common/signals-state-save-restore.c:64: internal-error: unexpected signal handler
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Aborted (core dumped)
$
The internal error comes from the code saving the signal dispositions
inherited from gdb's parent:
(top-gdb) bt
#0 0x000000000056b001 in internal_error(char const*, int, char const*, ...) (file=0xaf5f38 "src/gdb/common/signals-state-save-restore.c", line=64, fmt=0xaf5f18 "unexpected signal handler") at src/gdb/common/errors.c:54
#1 0x00000000005752c9 in save_original_signals_state() () at src/gdb/common/signals-state-save-restore.c:64
#2 0x00000000007425de in captured_main_1(captured_main_args*) (context=0x7fffffffd860)
at src/gdb/main.c:509
#3 0x0000000000743622 in captured_main(void*) (data=0x7fffffffd860) at src/gdb/main.c:1145
During symbol reading, cannot get low and high bounds for subprogram DIE at 24065.
#4 0x00000000007436f9 in gdb_main(captured_main_args*) (args=0x7fffffffd860) at src/gdb/main.c:1171
#5 0x0000000000413acd in main(int, char**) (argc=1, argv=0x7fffffffd968) at src/gdb/gdb.c:32
This commit downgrades the internal error to a warning. You'll get
instead:
~~~
$ LD_PRELOAD=libSegFault.so gdb
warning: Found custom handler for signal 11 (Segmentation fault) preinstalled.
Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)
won't be propagated to spawned programs.
GNU gdb (GDB) 8.0.50.20171213-git
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
(gdb)
~~~
This also moves the location where save_original_signals_state is
called a bit further below (to after option processing), so that "-q"
disables the warning:
~~~
$ LD_PRELOAD=libSegFault.so gdb -q
(gdb)
~~~
New testcase included.
gdb/ChangeLog:
2018-01-05 Pedro Alves <palves@redhat.com>
PR gdb/18653
* common/signals-state-save-restore.c
(save_original_signals_state): New parameter 'quiet'. Warn if we
find a custom handler preinstalled, instead of internal erroring.
But only warn if !quiet.
* common/signals-state-save-restore.h
(save_original_signals_state): New parameter 'quiet'.
* main.c (captured_main_1): Move save_original_signals_state call
after option handling, and pass QUIET.
gdb/gdbserver/ChangeLog:
2018-01-05 Pedro Alves <palves@redhat.com>
PR gdb/18653
* server.c (captured_main): Pass quiet=false to
save_original_signals_state.
gdb/testsuite/ChangeLog:
2018-01-05 Pedro Alves <palves@redhat.com>
PR gdb/18653
* gdb.base/libsegfault.exp: New.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,3 +1,15 @@
+2018-01-05 Pedro Alves <palves@redhat.com>
+
+ PR gdb/18653
+ * common/signals-state-save-restore.c
+ (save_original_signals_state): New parameter 'quiet'. Warn if we
+ find a custom handler preinstalled, instead of internal erroring.
+ But only warn if !quiet.
+ * common/signals-state-save-restore.h
+ (save_original_signals_state): New parameter 'quiet'.
+ * main.c (captured_main_1): Move save_original_signals_state call
+ after option handling, and pass QUIET.
+
2018-01-05 Pedro Alves <palves@redhat.com>
* spu-tdep.c (spu_catch_start): Pass
--- a/gdb/common/signals-state-save-restore.c
+++ b/gdb/common/signals-state-save-restore.c
@@ -35,7 +35,7 @@ static sigset_t original_signal_mask;
/* See signals-state-save-restore.h. */
void
-save_original_signals_state (void)
+save_original_signals_state (bool quiet)
{
#ifdef HAVE_SIGACTION
int i;
@@ -45,6 +45,8 @@ save_original_signals_state (void)
if (res == -1)
perror_with_name (("sigprocmask"));
+ bool found_preinstalled = false;
+
for (i = 1; i < NSIG; i++)
{
struct sigaction *oldact = &original_signal_actions[i];
@@ -59,9 +61,31 @@ save_original_signals_state (void)
perror_with_name (("sigaction"));
/* If we find a custom signal handler already installed, then
- this function was called too late. */
- if (oldact->sa_handler != SIG_DFL && oldact->sa_handler != SIG_IGN)
- internal_error (__FILE__, __LINE__, _("unexpected signal handler"));
+ this function was called too late. This is a warning instead
+ of an internal error because this can also happen if you
+ LD_PRELOAD a library that installs a signal handler early via
+ __attribute__((constructor)), like libSegFault.so. */
+ if (!quiet
+ && oldact->sa_handler != SIG_DFL
+ && oldact->sa_handler != SIG_IGN)
+ {
+ found_preinstalled = true;
+
+ /* Use raw fprintf here because we're being called in early
+ startup, because GDB's filtered streams are are
+ created. */
+ fprintf (stderr,
+ _("warning: Found custom handler for signal "
+ "%d (%s) preinstalled.\n"), i,
+ strsignal (i));
+ }
+ }
+
+ if (found_preinstalled)
+ {
+ fprintf (stderr, _("\
+Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)\n\
+won't be propagated to spawned programs.\n"));
}
#endif
}
--- a/gdb/common/signals-state-save-restore.h
+++ b/gdb/common/signals-state-save-restore.h
@@ -28,9 +28,10 @@
back to what was originally inherited from gdb/gdbserver's parent,
just before execing the target program to debug. */
-/* Save the signal state of all signals. */
+/* Save the signal state of all signals. If !QUIET, warn if we detect
+ a custom signal handler preinstalled. */
-extern void save_original_signals_state (void);
+extern void save_original_signals_state (bool quiet);
/* Restore the signal state of all signals. */
### a/gdb/gdbserver/ChangeLog
### b/gdb/gdbserver/ChangeLog
## -1,3 +1,9 @@
+2018-01-05 Pedro Alves <palves@redhat.com>
+
+ PR gdb/18653
+ * server.c (captured_main): Pass quiet=false to
+ save_original_signals_state.
+
2018-01-01 Joel Brobecker <brobecker@adacore.com>
* gdbreplay.c (gdbreplay_version): Update copyright year in
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -3712,7 +3712,7 @@ captured_main (int argc, char *argv[])
opened by remote_prepare. */
notice_open_fds ();
- save_original_signals_state ();
+ save_original_signals_state (false);
/* We need to know whether the remote connection is stdio before
starting the inferior. Inferiors created in this scenario have
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -506,7 +506,6 @@ captured_main_1 (struct captured_main_args *context)
bfd_init ();
notice_open_fds ();
- save_original_signals_state ();
saved_command_line = (char *) xstrdup ("");
@@ -849,6 +848,8 @@ captured_main_1 (struct captured_main_args *context)
quiet = 1;
}
+ save_original_signals_state (quiet);
+
/* Try to set up an alternate signal stack for SIGSEGV handlers. */
setup_alternate_signal_stack ();
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,3 +1,8 @@
+2018-01-05 Pedro Alves <palves@redhat.com>
+
+ PR gdb/18653
+ * gdb.base/libsegfault.exp: New.
+
2018-01-05 Joel Brobecker <brobecker@adacore.com>
PR gdb/22670
--- /dev/null
+++ b/gdb/testsuite/gdb.base/libsegfault.exp
@@ -0,0 +1,84 @@
+# Copyright 2017-2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+# Test that GDB tolerates being started with libSegFault.so preloaded
+# with LD_PRELOAD, and that GDB warns about a custom SIGSEGV custom
+# handler. See PR gdb/18653
+# <https://sourceware.org/bugzilla/show_bug.cgi?id=18653#c7>.
+
+# We cannot expect remote hosts to see environment variables set on
+# the local machine.
+if { [is_remote host] } {
+ unsupported "can't set environment variables on remote host"
+ return -1
+}
+
+# Spawn GDB with LIB preloaded with LD_PRELOAD. CMDLINE_OPTS are
+# command line options passed to GDB.
+
+proc gdb_spawn_with_ld_preload {lib cmdline_opts} {
+ global env
+
+ save_vars { env(LD_PRELOAD) } {
+ if { ![info exists env(LD_PRELOAD) ]
+ || $env(LD_PRELOAD) == "" } {
+ set env(LD_PRELOAD) "$lib"
+ } else {
+ append env(LD_PRELOAD) ":$lib"
+ }
+
+ gdb_spawn_with_cmdline_opts $cmdline_opts
+ }
+}
+
+proc test_libsegfault {} {
+ global gdb_prompt
+
+ set libsegfault "libSegFault.so"
+
+ # When started normally, if libSegFault.so is preloaded, GDB
+ # should warn about not being able to propagate the signal
+ # disposition of SIGSEGV.
+ gdb_exit
+ gdb_spawn_with_ld_preload $libsegfault ""
+
+ set test "gdb emits custom handler warning"
+ gdb_test_multiple "" $test {
+ -re "cannot be preloaded.*\r\n$gdb_prompt $" {
+ # Glibc 2.22 outputs:
+ # ERROR: ld.so: object 'libSegFault.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
+ untested "cannot preload libSegFault.so"
+ return
+ }
+ -re "Found custom handler.*won't be propagated.*\r\n$gdb_prompt $" {
+ pass $test
+ }
+ }
+
+ # "-q" should disable the warning, though.
+ gdb_exit
+ gdb_spawn_with_ld_preload $libsegfault "-q"
+
+ set test "quiet suppresses custom handler warning"
+ gdb_test_multiple "" $test {
+ -re "^$gdb_prompt $" {
+ pass $test
+ }
+ }
+}
+
+test_libsegfault

View File

@ -74,3 +74,461 @@ Date: Wed Aug 9 05:01:55 2017 -0700
|| attr->form == DW_FORM_GNU_strp_alt)
str = DW_STRING (attr);
else
commit f24b864960e61f9a91f8c168c1afe12a6676ad7a
Author: Walfred Tedeschi <walfred.tedeschi@intel.com>
Date: Mon Oct 16 08:59:38 2017 +0200
PR22137: gdbserver crashes on host with pkru register.
This patch adds missing backslash on a makefile and regenerate the
files created via the xml files. Those were not in sync with the xml file.
gdb/ChangeLog:
2017-10-16 Walfred Tedeschi <walfred.tedeschi@intel.com>
* features/Makefile (i386-avx-mpx-avx512-pku.dat): Add backslash
at the end of the line.
* regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat: Regenerate.
* regformats/i386/amd64-avx-mpx-avx512-pku.dat: Regenerate.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,3 +1,10 @@
+2017-10-16 Walfred Tedeschi <walfred.tedeschi@intel.com>
+
+ * features/Makefile (i386-avx-mpx-avx512-pku.dat): Add backslash
+ at the end of the line.
+ * regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat: Regenerate.
+ * regformats/i386/amd64-avx-mpx-avx512-pku.dat: Regenerate.
+
2017-09-07 Joel Brobecker <brobecker@adacore.com>
* version.in: Set GDB version number to 8.0.1.DATE-git.
--- a/gdb/features/Makefile
+++ b/gdb/features/Makefile
@@ -281,7 +281,7 @@ $(outdir)/i386/i386-avx-avx512.dat: i386/32bit-core.xml i386/32bit-avx.xml \
i386/32bit-avx512.xml
$(outdir)/i386/i386-avx-avx512-linux.dat: i386/32bit-core.xml i386/32bit-avx.xml \
i386/32bit-linux.xml i386/32bit-avx512.xml
-$(outdir)/i386/i386-avx-mpx-avx512-pku.dat: i386/32bit-core.xml
+$(outdir)/i386/i386-avx-mpx-avx512-pku.dat: i386/32bit-core.xml \
i386/32bit-avx.xml i386/32bit-mpx.xml i386/32bit-avx512.xml \
i386/32bit-pkeys.xml
$(outdir)/i386/i386-avx-mpx-avx512-pku-linux.dat: i386/32bit-core.xml \
--- a/gdb/regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat
+++ b/gdb/regformats/i386/amd64-avx-mpx-avx512-pku-linux.dat
@@ -157,3 +157,4 @@ expedite:rbp,rsp,rip
256:zmm29h
256:zmm30h
256:zmm31h
+32:pkru
--- a/gdb/regformats/i386/amd64-avx-mpx-avx512-pku.dat
+++ b/gdb/regformats/i386/amd64-avx-mpx-avx512-pku.dat
@@ -60,9 +60,6 @@ expedite:rbp,rsp,rip
128:xmm14
128:xmm15
32:mxcsr
-64:orig_rax
-64:fs_base
-64:gs_base
128:ymm0h
128:ymm1h
128:ymm2h
commit 50a1fdd59c1777672a9be0e81fe2301c2a115fce
Author: Pedro Alves <palves@redhat.com>
Date: Mon Dec 4 15:59:20 2017 +0000
Fix displaced-stepping RIP-relative VEX-encoded instructions (AVX) (PR gdb/22499)
PR gdb/22499 is about a latent bug exposed by the switch to "maint set
target-non-stop on" by default on x86-64 GNU/Linux, a while ago. With
that on, GDB is also preferring to use displaced-stepping by default.
The testcase in the bug is failing because GDB ends up incorrectly
displaced-stepping over a RIP-relative VEX-encoded instruction, like
this:
0x00000000004007f5 <+15>: c5 fb 10 05 8b 01 00 00 vmovsd 0x18b(%rip),%xmm0 # 0x400988
While RIP-relative instructions need adjustment when relocated to the
scratch pad, GDB ends up just copying VEX-encoded instructions to the
scratch pad unmodified, with the end result that the inferior ends up
executing an instruction that fetches/writes memory from the wrong
address...
This patch teaches GDB about the VEX-encoding prefixes, fixing the
problem, and adds a testcase that fails without the GDB fix.
I think we may need a similar treatment for EVEX-encoded instructions,
but I didn't address that simply because I couldn't find any
EVEX-encoded RIP-relative instruction in the gas testsuite. In any
case, this commit is forward progress as-is already.
gdb/ChangeLog:
2017-12-04 Pedro Alves <palves@redhat.com>
PR gdb/22499
* amd64-tdep.c (amd64_insn::rex_offset): Rename to...
(amd64_insn::enc_prefix_offset): ... this, and tweak comment.
(vex2_prefix_p, vex3_prefix_p): New functions.
(amd64_get_insn_details): Adjust to rename. Also skip VEX2 and
VEX3 prefixes.
(fixup_riprel): Set VEX3.!B.
gdb/testsuite/ChangeLog:
2017-12-04 Pedro Alves <palves@redhat.com>
PR gdb/22499
* gdb.arch/amd64-disp-step-avx.S: New file.
* gdb.arch/amd64-disp-step-avx.exp: New file.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,3 +1,13 @@
+2017-12-04 Pedro Alves <palves@redhat.com>
+
+ PR gdb/22499
+ * amd64-tdep.c (amd64_insn::rex_offset): Rename to...
+ (amd64_insn::enc_prefix_offset): ... this, and tweak comment.
+ (vex2_prefix_p, vex3_prefix_p): New functions.
+ (amd64_get_insn_details): Adjust to rename. Also skip VEX2 and
+ VEX3 prefixes.
+ (fixup_riprel): Set VEX3.!B.
+
2017-12-03 Simon Marchi <simon.marchi@ericsson.com>
* target.h (mem_region_vector): Remove.
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -1037,8 +1037,9 @@ struct amd64_insn
{
/* The number of opcode bytes. */
int opcode_len;
- /* The offset of the rex prefix or -1 if not present. */
- int rex_offset;
+ /* The offset of the REX/VEX instruction encoding prefix or -1 if
+ not present. */
+ int enc_prefix_offset;
/* The offset to the first opcode byte. */
int opcode_offset;
/* The offset to the modrm byte or -1 if not present. */
@@ -1124,6 +1125,22 @@ rex_prefix_p (gdb_byte pfx)
return REX_PREFIX_P (pfx);
}
+/* True if PFX is the start of the 2-byte VEX prefix. */
+
+static bool
+vex2_prefix_p (gdb_byte pfx)
+{
+ return pfx == 0xc5;
+}
+
+/* True if PFX is the start of the 3-byte VEX prefix. */
+
+static bool
+vex3_prefix_p (gdb_byte pfx)
+{
+ return pfx == 0xc4;
+}
+
/* Skip the legacy instruction prefixes in INSN.
We assume INSN is properly sentineled so we don't have to worry
about falling off the end of the buffer. */
@@ -1242,19 +1259,30 @@ amd64_get_insn_details (gdb_byte *insn, struct amd64_insn *details)
details->raw_insn = insn;
details->opcode_len = -1;
- details->rex_offset = -1;
+ details->enc_prefix_offset = -1;
details->opcode_offset = -1;
details->modrm_offset = -1;
/* Skip legacy instruction prefixes. */
insn = amd64_skip_prefixes (insn);
- /* Skip REX instruction prefix. */
+ /* Skip REX/VEX instruction encoding prefixes. */
if (rex_prefix_p (*insn))
{
- details->rex_offset = insn - start;
+ details->enc_prefix_offset = insn - start;
++insn;
}
+ else if (vex2_prefix_p (*insn))
+ {
+ /* Don't record the offset in this case because this prefix has
+ no REX.B equivalent. */
+ insn += 2;
+ }
+ else if (vex3_prefix_p (*insn))
+ {
+ details->enc_prefix_offset = insn - start;
+ insn += 3;
+ }
details->opcode_offset = insn - start;
@@ -1329,10 +1357,22 @@ fixup_riprel (struct gdbarch *gdbarch, amd64_displaced_step_closure *dsc,
arch_tmp_regno = amd64_get_unused_input_int_reg (insn_details);
tmp_regno = amd64_arch_reg_to_regnum (arch_tmp_regno);
- /* REX.B should be unset as we were using rip-relative addressing,
- but ensure it's unset anyway, tmp_regno is not r8-r15. */
- if (insn_details->rex_offset != -1)
- dsc->insn_buf[insn_details->rex_offset] &= ~REX_B;
+ /* Position of the not-B bit in the 3-byte VEX prefix (in byte 1). */
+ static constexpr gdb_byte VEX3_NOT_B = 0x20;
+
+ /* REX.B should be unset (VEX.!B set) as we were using rip-relative
+ addressing, but ensure it's unset (set for VEX) anyway, tmp_regno
+ is not r8-r15. */
+ if (insn_details->enc_prefix_offset != -1)
+ {
+ gdb_byte *pfx = &dsc->insn_buf[insn_details->enc_prefix_offset];
+ if (rex_prefix_p (pfx[0]))
+ pfx[0] &= ~REX_B;
+ else if (vex3_prefix_p (pfx[0]))
+ pfx[1] |= VEX3_NOT_B;
+ else
+ gdb_assert_not_reached ("unhandled prefix");
+ }
regcache_cooked_read_unsigned (regs, tmp_regno, &orig_value);
dsc->tmp_regno = tmp_regno;
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,3 +1,9 @@
+2017-12-04 Pedro Alves <palves@redhat.com>
+
+ PR gdb/22499
+ * gdb.arch/amd64-disp-step-avx.S: New file.
+ * gdb.arch/amd64-disp-step-avx.exp: New file.
+
2017-12-03 Pedro Alves <palves@redhat.com>
* gdb.threads/process-dies-while-detaching.c: Include <errno.h>
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.S
@@ -0,0 +1,70 @@
+/* Copyright 2009-2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ This file is part of the gdb testsuite.
+
+ Test displaced stepping over VEX-encoded RIP-relative AVX
+ instructions. */
+
+ .text
+
+ .global main
+main:
+ nop
+
+/***********************************************/
+
+/* Test a VEX2-encoded RIP-relative instruction. */
+
+ .global test_rip_vex2
+test_rip_vex2:
+ vmovsd ro_var(%rip),%xmm0
+ .global test_rip_vex2
+test_rip_vex2_end:
+ nop
+
+/* Test a VEX3-encoded RIP-relative instruction. */
+
+ .global test_rip_vex3
+test_rip_vex3:
+ vextractf128 $0x0,%ymm0,var128(%rip)
+ .global test_rip_vex3
+test_rip_vex3_end:
+ nop
+
+ /* skip over test data */
+ jmp done
+
+/* RIP-relative ro-data for VEX2 test above. */
+
+ro_var:
+ .8byte 0x1122334455667788
+ .8byte 0x8877665544332211
+
+/***********************************************/
+
+/* All done. */
+
+done:
+ mov $0,%rdi
+ call exit
+ hlt
+
+/* RIP-relative data for VEX3 test above. */
+
+.data
+var128:
+ .8byte 0xaa55aa55aa55aa55
+ .8byte 0x55aa55aa55aa55aa
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-disp-step-avx.exp
@@ -0,0 +1,141 @@
+# Copyright 2009-2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+# Test displaced stepping over VEX-encoded RIP-relative AVX
+# instructions.
+
+if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
+ verbose "Skipping x86_64 displaced stepping tests."
+ return
+}
+
+standard_testfile .S
+
+set additional_flags "-Wa,-g"
+
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+ [list debug $additional_flags]] } {
+ return -1
+}
+
+# Get things started.
+
+gdb_test "set displaced-stepping on" ""
+gdb_test "show displaced-stepping" ".* displaced stepping .* is on.*"
+
+if ![runto_main] then {
+ fail "can't run to main"
+ return 0
+}
+
+# GDB picks a spare register from this list to hold the RIP-relative
+# address.
+set rip_regs { "rax" "rbx" "rcx" "rdx" "rbp" "rsi" "rdi" }
+
+# Assign VAL to all the RIP_REGS.
+
+proc set_regs { val } {
+ global gdb_prompt
+ global rip_regs
+
+ foreach reg ${rip_regs} {
+ gdb_test_no_output "set \$${reg} = ${val}"
+ }
+}
+
+# Verify all RIP_REGS print as HEX_VAL_RE in hex.
+
+proc verify_regs { hex_val_re } {
+ global rip_regs
+
+ foreach reg ${rip_regs} {
+ gdb_test "p /x \$${reg}" " = ${hex_val_re}" "${reg} expected value"
+ }
+}
+
+# Set a break at FUNC, which starts with a RIP-relative instruction
+# that we want to displaced-step over, and then continue over the
+# breakpoint, forcing a displaced-stepping sequence.
+
+proc disp_step_func { func } {
+ global srcfile
+
+ set test_start_label "${func}"
+ set test_end_label "${func}_end"
+
+ gdb_test "break ${test_start_label}" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break ${test_start_label}"
+ gdb_test "break ${test_end_label}" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "break ${test_end_label}"
+
+ gdb_test "continue" \
+ "Continuing.*Breakpoint.*, ${test_start_label} ().*" \
+ "continue to ${test_start_label}"
+
+ # GDB picks a spare register to hold the RIP-relative address.
+ # Ensure the spare register value is restored properly (rax-rdi,
+ # sans rsp).
+ set value "0xdeadbeefd3adb33f"
+ set_regs $value
+
+ gdb_test "continue" \
+ "Continuing.*Breakpoint.*, ${test_end_label} ().*" \
+ "continue to ${test_end_label}"
+
+ verify_regs $value
+}
+
+# Test a VEX2-encoded RIP-relative instruction.
+with_test_prefix "vex2" {
+ # This case writes to the 'xmm0' register. Confirm the register's
+ # value is what we believe it is before the AVX instruction runs.
+ # Fedora: 0* for missing: https://sourceware.org/bugzilla/show_bug.cgi?id=16225
+ gdb_test "p /x \$xmm0.uint128" " = 0x00*" \
+ "xmm0 has expected value before"
+
+ disp_step_func "test_rip_vex2"
+
+ # Confirm the instruction's expected side effects. It should have
+ # modified xmm0.
+ # Fedora: 0* for missing: https://sourceware.org/bugzilla/show_bug.cgi?id=16225
+ gdb_test "p /x \$xmm0.uint128" " = 0x0*1122334455667788" \
+ "xmm0 has expected value after"
+}
+
+# Test a VEX3-encoded RIP-relative instruction.
+with_test_prefix "vex3" {
+ # This case writes to the 'var128' variable. Confirm the
+ # variable's value is what we believe it is before the AVX
+ # instruction runs.
+ gdb_test "p /x (unsigned long long \[2\]) var128" \
+ " = \\{0xaa55aa55aa55aa55, 0x55aa55aa55aa55aa\\}" \
+ "var128 has expected value before"
+
+ # Run the AVX instruction.
+ disp_step_func "test_rip_vex3"
+
+ # Confirm the instruction's expected side effects. It should have
+ # modifed the 'var128' variable.
+ gdb_test "p /x (unsigned long long \[2\]) var128" \
+ " = \\{0x1122334455667788, 0x0\\}" \
+ "var128 has expected value after"
+}
+
+# Done, run program to exit.
+gdb_continue_to_end "amd64-disp-step-avx"

View File

@ -20,13 +20,13 @@ Name: %{?scl_prefix}gdb
# Freeze it when GDB gets branched
%global snapsrc 20170420
# See timestamp of source gnulib installed into gdb/gnulib/ .
%global snapgnulib 20150822
%global snapgnulib 20161115
%global tarname gdb-%{version}
Version: 8.0.1
# The release always contains a leading reserved number, start it at 1.
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
Release: 31%{?dist}
Release: 36%{?dist}
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL
Group: Development/Debuggers
@ -737,6 +737,13 @@ Patch1259: gdb-rhbz1498758-5of5.patch
Patch1261: gdb-rhbz1228556-bpt-inlined-func-name-1of2.patch
Patch1262: gdb-rhbz1228556-bpt-inlined-func-name-2of2.patch
# Fix random 'FAIL: libstdc++-prettyprinters/80276.cc whatis p4' (GCC
# PR83906) (Pedro Alves).
Patch1263: gdb-random-libstdcpp-prettyprinters-fail.patch
# Fix signal handlers regression (RH BZ 1542149, Pedro Alves).
Patch1270: gdb-rhbz1542149-spawn-default-signal-handlers-regression.patch
%if 0%{!?rhel:1} || 0%{?rhel} > 6
# RL_STATE_FEDORA_GDB would not be found for:
# Patch642: gdb-readline62-ask-more-rh.patch
@ -1149,6 +1156,8 @@ done
%patch1259 -p1
%patch1261 -p1
%patch1262 -p1
%patch1263 -p1
%patch1270 -p1
%patch1075 -p1
%if 0%{?rhel:1} && 0%{?rhel} <= 7
@ -1731,6 +1740,24 @@ then
fi
%changelog
* Tue Feb 6 2018 Jan Kratochvil <jan.kratochvil@redhat.com> - 8.0.1-36.fc26
- Fix signal handlers regression (RH BZ 1542149, Pedro Alves).
* Thu Jan 25 2018 Sergio Durigan Junior <sergiodj@redhat.com> - 8.0.1-35.fc26
- Add %patch directive to the commit below.
* Wed Jan 24 2018 Sergio Durigan Junior <sergiodj@fedoraproject.org> - 8.0.1-34.fc26
- Fix random 'FAIL: libstdc++-prettyprinters/80276.cc whatis p4' (GCC PR83906)
(Pedro Alves).
* Wed Dec 6 2017 Jan Kratochvil <jan.kratochvil@redhat.com> - 8.0.1-33.fc26
- [rhel7] Fix C++ compiler compatibility.
* Tue Dec 5 2017 Jan Kratochvil <jan.kratochvil@redhat.com> - 8.0.1-32.fc26
- Backport upstream fix for Intel PKRU (Walfred Tedeschi).
- Backport upstream fix AVX instr. single-stepping (RH BZ 1515209, Pedro Alves).
- Fix snapgnulib bundle number.
* Sat Dec 2 2017 Jan Kratochvil <jan.kratochvil@redhat.com> - 8.0.1-31.fc26
- [testsuite] Fix BuildRequires for non-x86* arches.