]> git.pld-linux.org Git - packages/gdb.git/commitdiff
- rel 2; x32 fixes auto/th/gdb-7.11.1-2
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Tue, 23 Aug 2016 17:15:05 +0000 (19:15 +0200)
committerArkadiusz Miśkiewicz <arekm@maven.pl>
Tue, 23 Aug 2016 17:15:05 +0000 (19:15 +0200)
gdb-bug-20287.patch [new file with mode: 0644]
gdb-bug-20413.patch [new file with mode: 0644]
gdb.spec

diff --git a/gdb-bug-20287.patch b/gdb-bug-20287.patch
new file mode 100644 (file)
index 0000000..e1da98a
--- /dev/null
@@ -0,0 +1,634 @@
+From 9cf12d57c58a82cfe3e6fee26d1ea55dfe49f9c4 Mon Sep 17 00:00:00 2001
+From: Pedro Alves <palves@redhat.com>
+Date: Tue, 26 Jul 2016 19:35:40 +0100
+Subject: [PATCH] Fix PR gdb/20287 - x32 and "gdb_static_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t))"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+Building an x32 gdb trips on a static assertion:
+
+  In file included from .../src/gdb/common/common-defs.h:71:0,
+                  from .../src/gdb/nat/amd64-linux-siginfo.c:21:
+  .../src/gdb/common/gdb_assert.h:26:66: error: size of array â\80\98never_defined_just_used_for_checkingâ\80\99 is negative
+     extern int never_defined_just_used_for_checking[(expr) ? 1 : -1]
+                                                                   ^
+  .../src/gdb/nat/amd64-linux-siginfo.c:113:1: note: in expansion of macro â\80\98gdb_static_assertâ\80\99
+   gdb_static_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+   ^
+
+The problem is that the way nat_siginfo_t is defined, it can only
+match the host's siginfo_t object when gdb is built as a 64-bit
+program.
+
+Several bits of nat_siginfo_t are off:
+
+- nat_siginfo_t's _pad field's definition is:
+
+   int _pad[((128 / sizeof (int)) - 4)];
+
+  while /usr/include/bits/siginfo.h has:
+
+   # define __SI_MAX_SIZE     128
+   # if __WORDSIZE == 64
+   #  define __SI_PAD_SIZE     ((__SI_MAX_SIZE / sizeof (int)) - 4)
+   # else
+   #  define __SI_PAD_SIZE     ((__SI_MAX_SIZE / sizeof (int)) - 3)
+   # endif
+
+  and __WORDSIZE == 32 for x32.  This is what causes the size of
+  nat_siginfo_t to be wrong and the assertion to fail.
+
+- the nat_clock_t type is incorrect for 64-bit.  We have this:
+
+   /* For native 64-bit, clock_t in _sigchld is 64bit aligned at 4 bytes.  */
+   typedef long __attribute__ ((__aligned__ (4))) nat_clock_t;
+
+  however, /usr/include/bits/siginfo.h has:
+
+   # if defined __x86_64__ && __WORDSIZE == 32
+   /* si_utime and si_stime must be 4 byte aligned for x32 to match the
+      kernel.  We align siginfo_t to 8 bytes so that si_utime and si_stime
+      are actually aligned to 8 bytes since their offsets are multiple of
+      8 bytes.  */
+   typedef __clock_t __attribute__ ((__aligned__ (4))) __sigchld_clock_t;
+   #  define __SI_ALIGNMENT __attribute__ ((__aligned__ (8)))
+   # else
+   typedef __clock_t __sigchld_clock_t;
+   #  define __SI_ALIGNMENT
+   # endif
+
+  So we're currently forcing 4-byte alignment on clock_t, when it
+  should only be so for x32, not 64-bit.
+
+The fix:
+
+ - Leaves nat_siginfo_t strictly for the 64-bit ABI.
+
+ - Adds a new typedef for the siginfo type that ptrace uses
+   (ptrace_siginfo_t).  An x32 gdb always gets/sets an x32 siginfo_t
+   type with PTRACE_GETSIGINFO/PTRACE_SETSIGINFO.
+
+ - Uses this new ptrace_siginfo_t type instead of nat_siginfo_t as the
+   intermediate conversion type.
+
+diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
+index 391a646..fea6ee2 100644
+--- a/gdb/amd64-linux-nat.c
++++ b/gdb/amd64-linux-nat.c
+@@ -321,25 +321,25 @@ ps_get_thread_area (const struct ps_prochandle *ph,
+ }
\f
+-/* Convert a native/host siginfo object, into/from the siginfo in the
++/* Convert a ptrace/host siginfo object, into/from the siginfo in the
+    layout of the inferiors' architecture.  Returns true if any
+    conversion was done; false otherwise.  If DIRECTION is 1, then copy
+-   from INF to NATIVE.  If DIRECTION is 0, copy from NATIVE to
++   from INF to PTRACE.  If DIRECTION is 0, copy from PTRACE to
+    INF.  */
+ static int
+-amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
++amd64_linux_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
+ {
+   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
+   /* Is the inferior 32-bit?  If so, then do fixup the siginfo
+      object.  */
+   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+-      return amd64_linux_siginfo_fixup_common (native, inf, direction,
++      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
+                                              FIXUP_32);
+   /* No fixup for native x32 GDB.  */
+   else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
+-      return amd64_linux_siginfo_fixup_common (native, inf, direction,
++      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
+                                              FIXUP_X32);
+   else
+     return 0;
+diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
+index 5080dec..4e6dbce 100644
+--- a/gdb/gdbserver/linux-x86-low.c
++++ b/gdb/gdbserver/linux-x86-low.c
+@@ -624,14 +624,14 @@ x86_debug_reg_state (pid_t pid)
+    as debugging it with a 32-bit GDBSERVER, we do the 32-bit <-> 64-bit
+    conversion in-place ourselves.  */
+-/* Convert a native/host siginfo object, into/from the siginfo in the
++/* Convert a ptrace/host siginfo object, into/from the siginfo in the
+    layout of the inferiors' architecture.  Returns true if any
+    conversion was done; false otherwise.  If DIRECTION is 1, then copy
+-   from INF to NATIVE.  If DIRECTION is 0, copy from NATIVE to
++   from INF to PTRACE.  If DIRECTION is 0, copy from PTRACE to
+    INF.  */
+ static int
+-x86_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
++x86_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
+ {
+ #ifdef __x86_64__
+   unsigned int machine;
+@@ -640,11 +640,11 @@ x86_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
+   /* Is the inferior 32-bit?  If so, then fixup the siginfo object.  */
+   if (!is_64bit_tdesc ())
+-      return amd64_linux_siginfo_fixup_common (native, inf, direction,
++      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
+                                              FIXUP_32);
+   /* No fixup for native x32 GDB.  */
+   else if (!is_elf64 && sizeof (void *) == 8)
+-    return amd64_linux_siginfo_fixup_common (native, inf, direction,
++    return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
+                                            FIXUP_X32);
+ #endif
+diff --git a/gdb/nat/amd64-linux-siginfo.c b/gdb/nat/amd64-linux-siginfo.c
+index 72b3042..9f7df0c 100644
+--- a/gdb/nat/amd64-linux-siginfo.c
++++ b/gdb/nat/amd64-linux-siginfo.c
+@@ -21,23 +21,29 @@
+ #include "common-defs.h"
+ #include "amd64-linux-siginfo.h"
+-/* The nat_* types below define the most complete kernel siginfo type
+-   known for the architecture, independent of the system/libc headers.  */
++#define GDB_SI_SIZE 128
++
++/* The types below define the most complete kernel siginfo types known
++   for the architecture, independent of the system/libc headers.  They
++   are named from a 64-bit kernel's perspective:
++
++   | layout | type                 |
++   |--------+----------------------|
++   | 64-bit | nat_siginfo_t        |
++   | 32-bit | compat_siginfo_t     |
++   | x32    | compat_x32_siginfo_t |
++*/
++
++#ifndef __ILP32__
+ typedef int nat_int_t;
+-typedef void* nat_uptr_t;
++typedef unsigned long nat_uptr_t;
+ typedef int nat_time_t;
+ typedef int nat_timer_t;
+-/* For native 64-bit, clock_t in _sigchld is 64bit aligned at 4 bytes.  */
+-typedef long __attribute__ ((__aligned__ (4))) nat_clock_t;
+-
+-struct nat_timeval
+-{
+-  nat_time_t tv_sec;
+-  int tv_usec;
+-};
++/* For native 64-bit, clock_t in _sigchld is 64-bit.  */
++typedef long nat_clock_t;
+ typedef union nat_sigval
+ {
+@@ -106,11 +112,9 @@ typedef struct nat_siginfo
+       int _fd;
+     } _sigpoll;
+   } _sifields;
+-} nat_siginfo_t __attribute__ ((__aligned__ (8)));
+-
+-/*  Sanity check for the siginfo structure size.  */
++} nat_siginfo_t;
+-gdb_static_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
++#endif /* __ILP32__ */
+ /* These types below (compat_*) define a siginfo type that is layout
+    compatible with the siginfo type exported by the 32-bit userspace
+@@ -286,62 +290,71 @@ typedef struct compat_x32_siginfo
+ #define si_overrun si_timer2
+ #endif
++/* The type of the siginfo object the kernel returns in
++   PTRACE_GETSIGINFO.  If gdb is built as a x32 program, we get a x32
++   siginfo.  */
++#ifdef __ILP32__
++typedef compat_x32_siginfo_t ptrace_siginfo_t;
++#else
++typedef nat_siginfo_t ptrace_siginfo_t;
++#endif
++
+ /*  Convert the system provided siginfo into compatible siginfo.  */
+ static void
+-compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
++compat_siginfo_from_siginfo (compat_siginfo_t *to, const siginfo_t *from)
+ {
+-  nat_siginfo_t from_nat;
++  ptrace_siginfo_t from_ptrace;
+-  memcpy (&from_nat, from, sizeof (from_nat));
++  memcpy (&from_ptrace, from, sizeof (from_ptrace));
+   memset (to, 0, sizeof (*to));
+-  to->si_signo = from_nat.si_signo;
+-  to->si_errno = from_nat.si_errno;
+-  to->si_code = from_nat.si_code;
++  to->si_signo = from_ptrace.si_signo;
++  to->si_errno = from_ptrace.si_errno;
++  to->si_code = from_ptrace.si_code;
+   if (to->si_code == SI_TIMER)
+     {
+-      to->cpt_si_timerid = from_nat.cpt_si_timerid;
+-      to->cpt_si_overrun = from_nat.cpt_si_overrun;
+-      to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
++      to->cpt_si_timerid = from_ptrace.cpt_si_timerid;
++      to->cpt_si_overrun = from_ptrace.cpt_si_overrun;
++      to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
+     }
+   else if (to->si_code == SI_USER)
+     {
+-      to->cpt_si_pid = from_nat.cpt_si_pid;
+-      to->cpt_si_uid = from_nat.cpt_si_uid;
++      to->cpt_si_pid = from_ptrace.cpt_si_pid;
++      to->cpt_si_uid = from_ptrace.cpt_si_uid;
+     }
+   else if (to->si_code < 0)
+     {
+-      to->cpt_si_pid = from_nat.cpt_si_pid;
+-      to->cpt_si_uid = from_nat.cpt_si_uid;
+-      to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
++      to->cpt_si_pid = from_ptrace.cpt_si_pid;
++      to->cpt_si_uid = from_ptrace.cpt_si_uid;
++      to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
+     }
+   else
+     {
+       switch (to->si_signo)
+       {
+       case SIGCHLD:
+-        to->cpt_si_pid = from_nat.cpt_si_pid;
+-        to->cpt_si_uid = from_nat.cpt_si_uid;
+-        to->cpt_si_status = from_nat.cpt_si_status;
+-        to->cpt_si_utime = from_nat.cpt_si_utime;
+-        to->cpt_si_stime = from_nat.cpt_si_stime;
++        to->cpt_si_pid = from_ptrace.cpt_si_pid;
++        to->cpt_si_uid = from_ptrace.cpt_si_uid;
++        to->cpt_si_status = from_ptrace.cpt_si_status;
++        to->cpt_si_utime = from_ptrace.cpt_si_utime;
++        to->cpt_si_stime = from_ptrace.cpt_si_stime;
+         break;
+       case SIGILL:
+       case SIGFPE:
+       case SIGSEGV:
+       case SIGBUS:
+-        to->cpt_si_addr = (intptr_t) from_nat.cpt_si_addr;
++        to->cpt_si_addr = from_ptrace.cpt_si_addr;
+         break;
+       case SIGPOLL:
+-        to->cpt_si_band = from_nat.cpt_si_band;
+-        to->cpt_si_fd = from_nat.cpt_si_fd;
++        to->cpt_si_band = from_ptrace.cpt_si_band;
++        to->cpt_si_fd = from_ptrace.cpt_si_fd;
+         break;
+       default:
+-        to->cpt_si_pid = from_nat.cpt_si_pid;
+-        to->cpt_si_uid = from_nat.cpt_si_uid;
+-        to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
++        to->cpt_si_pid = from_ptrace.cpt_si_pid;
++        to->cpt_si_uid = from_ptrace.cpt_si_uid;
++        to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
+         break;
+       }
+     }
+@@ -350,124 +363,124 @@ compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
+ /* Convert the compatible siginfo into system siginfo.  */
+ static void
+-siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
++siginfo_from_compat_siginfo (siginfo_t *to, const compat_siginfo_t *from)
+ {
+-  nat_siginfo_t to_nat;
++  ptrace_siginfo_t to_ptrace;
+-  memset (&to_nat, 0, sizeof (to_nat));
++  memset (&to_ptrace, 0, sizeof (to_ptrace));
+-  to_nat.si_signo = from->si_signo;
+-  to_nat.si_errno = from->si_errno;
+-  to_nat.si_code = from->si_code;
++  to_ptrace.si_signo = from->si_signo;
++  to_ptrace.si_errno = from->si_errno;
++  to_ptrace.si_code = from->si_code;
+-  if (to_nat.si_code == SI_TIMER)
++  if (to_ptrace.si_code == SI_TIMER)
+     {
+-      to_nat.cpt_si_timerid = from->cpt_si_timerid;
+-      to_nat.cpt_si_overrun = from->cpt_si_overrun;
+-      to_nat.cpt_si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
++      to_ptrace.cpt_si_timerid = from->cpt_si_timerid;
++      to_ptrace.cpt_si_overrun = from->cpt_si_overrun;
++      to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
+     }
+-  else if (to_nat.si_code == SI_USER)
++  else if (to_ptrace.si_code == SI_USER)
+     {
+-      to_nat.cpt_si_pid = from->cpt_si_pid;
+-      to_nat.cpt_si_uid = from->cpt_si_uid;
++      to_ptrace.cpt_si_pid = from->cpt_si_pid;
++      to_ptrace.cpt_si_uid = from->cpt_si_uid;
+     }
+-  if (to_nat.si_code < 0)
++  if (to_ptrace.si_code < 0)
+     {
+-      to_nat.cpt_si_pid = from->cpt_si_pid;
+-      to_nat.cpt_si_uid = from->cpt_si_uid;
+-      to_nat.cpt_si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
++      to_ptrace.cpt_si_pid = from->cpt_si_pid;
++      to_ptrace.cpt_si_uid = from->cpt_si_uid;
++      to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
+     }
+   else
+     {
+-      switch (to_nat.si_signo)
++      switch (to_ptrace.si_signo)
+       {
+       case SIGCHLD:
+-        to_nat.cpt_si_pid = from->cpt_si_pid;
+-        to_nat.cpt_si_uid = from->cpt_si_uid;
+-        to_nat.cpt_si_status = from->cpt_si_status;
+-        to_nat.cpt_si_utime = from->cpt_si_utime;
+-        to_nat.cpt_si_stime = from->cpt_si_stime;
++        to_ptrace.cpt_si_pid = from->cpt_si_pid;
++        to_ptrace.cpt_si_uid = from->cpt_si_uid;
++        to_ptrace.cpt_si_status = from->cpt_si_status;
++        to_ptrace.cpt_si_utime = from->cpt_si_utime;
++        to_ptrace.cpt_si_stime = from->cpt_si_stime;
+         break;
+       case SIGILL:
+       case SIGFPE:
+       case SIGSEGV:
+       case SIGBUS:
+-        to_nat.cpt_si_addr = (void *) (intptr_t) from->cpt_si_addr;
+-        to_nat.cpt_si_addr_lsb = (short) from->cpt_si_addr_lsb;
++        to_ptrace.cpt_si_addr = from->cpt_si_addr;
++        to_ptrace.cpt_si_addr_lsb = from->cpt_si_addr_lsb;
+         break;
+       case SIGPOLL:
+-        to_nat.cpt_si_band = from->cpt_si_band;
+-        to_nat.cpt_si_fd = from->cpt_si_fd;
++        to_ptrace.cpt_si_band = from->cpt_si_band;
++        to_ptrace.cpt_si_fd = from->cpt_si_fd;
+         break;
+       default:
+-        to_nat.cpt_si_pid = from->cpt_si_pid;
+-        to_nat.cpt_si_uid = from->cpt_si_uid;
+-        to_nat.cpt_si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
++        to_ptrace.cpt_si_pid = from->cpt_si_pid;
++        to_ptrace.cpt_si_uid = from->cpt_si_uid;
++        to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
+         break;
+       }
+     }
+-  memcpy (to, &to_nat, sizeof (to_nat));
++  memcpy (to, &to_ptrace, sizeof (to_ptrace));
+ }
+ /*  Convert the system provided siginfo into compatible x32 siginfo.  */
+ static void
+ compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
+-                               siginfo_t *from)
++                               const siginfo_t *from)
+ {
+-  nat_siginfo_t from_nat;
++  ptrace_siginfo_t from_ptrace;
+-  memcpy (&from_nat, from, sizeof (from_nat));
++  memcpy (&from_ptrace, from, sizeof (from_ptrace));
+   memset (to, 0, sizeof (*to));
+-  to->si_signo = from_nat.si_signo;
+-  to->si_errno = from_nat.si_errno;
+-  to->si_code = from_nat.si_code;
++  to->si_signo = from_ptrace.si_signo;
++  to->si_errno = from_ptrace.si_errno;
++  to->si_code = from_ptrace.si_code;
+   if (to->si_code == SI_TIMER)
+     {
+-      to->cpt_si_timerid = from_nat.cpt_si_timerid;
+-      to->cpt_si_overrun = from_nat.cpt_si_overrun;
+-      to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
++      to->cpt_si_timerid = from_ptrace.cpt_si_timerid;
++      to->cpt_si_overrun = from_ptrace.cpt_si_overrun;
++      to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
+     }
+   else if (to->si_code == SI_USER)
+     {
+-      to->cpt_si_pid = from_nat.cpt_si_pid;
+-      to->cpt_si_uid = from_nat.cpt_si_uid;
++      to->cpt_si_pid = from_ptrace.cpt_si_pid;
++      to->cpt_si_uid = from_ptrace.cpt_si_uid;
+     }
+   else if (to->si_code < 0)
+     {
+-      to->cpt_si_pid = from_nat.cpt_si_pid;
+-      to->cpt_si_uid = from_nat.cpt_si_uid;
+-      to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
++      to->cpt_si_pid = from_ptrace.cpt_si_pid;
++      to->cpt_si_uid = from_ptrace.cpt_si_uid;
++      to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
+     }
+   else
+     {
+       switch (to->si_signo)
+       {
+       case SIGCHLD:
+-        to->cpt_si_pid = from_nat.cpt_si_pid;
+-        to->cpt_si_uid = from_nat.cpt_si_uid;
+-        to->cpt_si_status = from_nat.cpt_si_status;
+-        memcpy (&to->cpt_si_utime, &from_nat.cpt_si_utime,
++        to->cpt_si_pid = from_ptrace.cpt_si_pid;
++        to->cpt_si_uid = from_ptrace.cpt_si_uid;
++        to->cpt_si_status = from_ptrace.cpt_si_status;
++        memcpy (&to->cpt_si_utime, &from_ptrace.cpt_si_utime,
+                 sizeof (to->cpt_si_utime));
+-        memcpy (&to->cpt_si_stime, &from_nat.cpt_si_stime,
++        memcpy (&to->cpt_si_stime, &from_ptrace.cpt_si_stime,
+                 sizeof (to->cpt_si_stime));
+         break;
+       case SIGILL:
+       case SIGFPE:
+       case SIGSEGV:
+       case SIGBUS:
+-        to->cpt_si_addr = (intptr_t) from_nat.cpt_si_addr;
++        to->cpt_si_addr = from_ptrace.cpt_si_addr;
+         break;
+       case SIGPOLL:
+-        to->cpt_si_band = from_nat.cpt_si_band;
+-        to->cpt_si_fd = from_nat.cpt_si_fd;
++        to->cpt_si_band = from_ptrace.cpt_si_band;
++        to->cpt_si_fd = from_ptrace.cpt_si_fd;
+         break;
+       default:
+-        to->cpt_si_pid = from_nat.cpt_si_pid;
+-        to->cpt_si_uid = from_nat.cpt_si_uid;
+-        to->cpt_si_ptr = (intptr_t) from_nat.cpt_si_ptr;
++        to->cpt_si_pid = from_ptrace.cpt_si_pid;
++        to->cpt_si_uid = from_ptrace.cpt_si_uid;
++        to->cpt_si_ptr = from_ptrace.cpt_si_ptr;
+         break;
+       }
+     }
+@@ -479,98 +492,105 @@ compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
+ /* Convert the compatible x32 siginfo into system siginfo.  */
+ static void
+ siginfo_from_compat_x32_siginfo (siginfo_t *to,
+-                               compat_x32_siginfo_t *from)
++                               const compat_x32_siginfo_t *from)
+ {
+-  nat_siginfo_t to_nat;
++  ptrace_siginfo_t to_ptrace;
+-  memset (&to_nat, 0, sizeof (to_nat));
+-  to_nat.si_signo = from->si_signo;
+-  to_nat.si_errno = from->si_errno;
+-  to_nat.si_code = from->si_code;
++  memset (&to_ptrace, 0, sizeof (to_ptrace));
++  to_ptrace.si_signo = from->si_signo;
++  to_ptrace.si_errno = from->si_errno;
++  to_ptrace.si_code = from->si_code;
+-  if (to_nat.si_code == SI_TIMER)
++  if (to_ptrace.si_code == SI_TIMER)
+     {
+-      to_nat.cpt_si_timerid = from->cpt_si_timerid;
+-      to_nat.cpt_si_overrun = from->cpt_si_overrun;
+-      to_nat.cpt_si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
++      to_ptrace.cpt_si_timerid = from->cpt_si_timerid;
++      to_ptrace.cpt_si_overrun = from->cpt_si_overrun;
++      to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
+     }
+-  else if (to_nat.si_code == SI_USER)
++  else if (to_ptrace.si_code == SI_USER)
+     {
+-      to_nat.cpt_si_pid = from->cpt_si_pid;
+-      to_nat.cpt_si_uid = from->cpt_si_uid;
++      to_ptrace.cpt_si_pid = from->cpt_si_pid;
++      to_ptrace.cpt_si_uid = from->cpt_si_uid;
+     }
+-  if (to_nat.si_code < 0)
++  if (to_ptrace.si_code < 0)
+     {
+-      to_nat.cpt_si_pid = from->cpt_si_pid;
+-      to_nat.cpt_si_uid = from->cpt_si_uid;
+-      to_nat.cpt_si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
++      to_ptrace.cpt_si_pid = from->cpt_si_pid;
++      to_ptrace.cpt_si_uid = from->cpt_si_uid;
++      to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
+     }
+   else
+     {
+-      switch (to_nat.si_signo)
++      switch (to_ptrace.si_signo)
+       {
+       case SIGCHLD:
+-        to_nat.cpt_si_pid = from->cpt_si_pid;
+-        to_nat.cpt_si_uid = from->cpt_si_uid;
+-        to_nat.cpt_si_status = from->cpt_si_status;
+-        memcpy (&to_nat.cpt_si_utime, &from->cpt_si_utime,
+-                sizeof (to_nat.cpt_si_utime));
+-        memcpy (&to_nat.cpt_si_stime, &from->cpt_si_stime,
+-                sizeof (to_nat.cpt_si_stime));
++        to_ptrace.cpt_si_pid = from->cpt_si_pid;
++        to_ptrace.cpt_si_uid = from->cpt_si_uid;
++        to_ptrace.cpt_si_status = from->cpt_si_status;
++        memcpy (&to_ptrace.cpt_si_utime, &from->cpt_si_utime,
++                sizeof (to_ptrace.cpt_si_utime));
++        memcpy (&to_ptrace.cpt_si_stime, &from->cpt_si_stime,
++                sizeof (to_ptrace.cpt_si_stime));
+         break;
+       case SIGILL:
+       case SIGFPE:
+       case SIGSEGV:
+       case SIGBUS:
+-        to_nat.cpt_si_addr = (void *) (intptr_t) from->cpt_si_addr;
++        to_ptrace.cpt_si_addr = from->cpt_si_addr;
+         break;
+       case SIGPOLL:
+-        to_nat.cpt_si_band = from->cpt_si_band;
+-        to_nat.cpt_si_fd = from->cpt_si_fd;
++        to_ptrace.cpt_si_band = from->cpt_si_band;
++        to_ptrace.cpt_si_fd = from->cpt_si_fd;
+         break;
+       default:
+-        to_nat.cpt_si_pid = from->cpt_si_pid;
+-        to_nat.cpt_si_uid = from->cpt_si_uid;
+-        to_nat.cpt_si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
++        to_ptrace.cpt_si_pid = from->cpt_si_pid;
++        to_ptrace.cpt_si_uid = from->cpt_si_uid;
++        to_ptrace.cpt_si_ptr = from->cpt_si_ptr;
+         break;
+       }
+     }
+-  memcpy (to, &to_nat, sizeof (to_nat));
++  memcpy (to, &to_ptrace, sizeof (to_ptrace));
+ }
+-/* Convert a native/host siginfo object, into/from the siginfo in the
++/* Convert a ptrace siginfo object, into/from the siginfo in the
+    layout of the inferiors' architecture.  Returns true if any
+    conversion was done; false otherwise.  If DIRECTION is 1, then copy
+-   from INF to NATIVE.  If DIRECTION is 0, then copy from NATIVE to INF.  */
++   from INF to PTRACE.  If DIRECTION is 0, then copy from NATIVE to
++   INF.  */
+ int
+-amd64_linux_siginfo_fixup_common (siginfo_t *native, gdb_byte *inf,
++amd64_linux_siginfo_fixup_common (siginfo_t *ptrace, gdb_byte *inf,
+                                 int direction,
+                                 enum amd64_siginfo_fixup_mode mode)
+ {
+   if (mode == FIXUP_32)
+     {
+-      gdb_assert (sizeof (siginfo_t) == sizeof (compat_siginfo_t));
+-
+       if (direction == 0)
+-      compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native);
++      compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, ptrace);
+       else
+-      siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf);
++      siginfo_from_compat_siginfo (ptrace, (struct compat_siginfo *) inf);
+       return 1;
+     }
+   else if (mode == FIXUP_X32)
+     {
+-      gdb_assert (sizeof (siginfo_t) == sizeof (compat_x32_siginfo_t));
+-
+       if (direction == 0)
+       compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf,
+-                                       native);
++                                       ptrace);
+       else
+-      siginfo_from_compat_x32_siginfo (native,
++      siginfo_from_compat_x32_siginfo (ptrace,
+                                        (struct compat_x32_siginfo *) inf);
+       return 1;
+     }
+   return 0;
+ }
++
++/* Sanity check for the siginfo structure sizes.  */
++
++gdb_static_assert (sizeof (siginfo_t) == GDB_SI_SIZE);
++#ifndef __ILP32__
++gdb_static_assert (sizeof (nat_siginfo_t) == GDB_SI_SIZE);
++#endif
++gdb_static_assert (sizeof (compat_x32_siginfo_t) == GDB_SI_SIZE);
++gdb_static_assert (sizeof (compat_siginfo_t) == GDB_SI_SIZE);
++gdb_static_assert (sizeof (ptrace_siginfo_t) == GDB_SI_SIZE);
+-- 
+1.7.1
+
diff --git a/gdb-bug-20413.patch b/gdb-bug-20413.patch
new file mode 100644 (file)
index 0000000..f8763f9
--- /dev/null
@@ -0,0 +1,111 @@
+From 40c31709c6a51926fcb409611caa52b2da6515c0 Mon Sep 17 00:00:00 2001
+From: Pedro Alves <palves@redhat.com>
+Date: Tue, 26 Jul 2016 19:35:40 +0100
+Subject: [PATCH] Fix PR gdb/20413 - x32: linux_ptrace_test_ret_to_nx: Cannot PTRACE_PEEKUSER
+
+An x32 gdb always issues this warning:
+
+ (gdb) start
+ Temporary breakpoint 1 at 0x4043e9: file foo.c, line 25.
+ Starting program: a.out
+ warning: linux_ptrace_test_ret_to_nx: Cannot PTRACE_PEEKUSER: Input/output error
+
+ Temporary breakpoint 1, main (argc=1, argv=0xffffd544) at foo.c:25
+ 25      {
+ (gdb)
+
+As described in Linux commit 55283e253771 (x32: Add ptrace for x32):
+
+    [...] PTRACE_PEEKUSR and PTRACE_POKEUSR are only allowed to access
+    segment and debug registers. [...]
+
+The fix is to use PTRACE_GETREGS instead.
+
+diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c
+index 0eaf9a3..980ed53 100644
+--- a/gdb/nat/linux-ptrace.c
++++ b/gdb/nat/linux-ptrace.c
+@@ -23,6 +23,7 @@
+ #include "buffer.h"
+ #include "gdb_wait.h"
+ #include "gdb_ptrace.h"
++#include "gregset.h"
+ /* Stores the ptrace options supported by the running kernel.
+    A value of -1 means we did not check for features yet.  A value
+@@ -100,6 +101,7 @@ linux_ptrace_test_ret_to_nx (void)
+   gdb_byte *return_address, *pc;
+   long l;
+   int status, kill_status;
++  elf_gregset_t regs;
+   return_address
+     = (gdb_byte *) mmap (NULL, 2, PROT_READ | PROT_WRITE,
+@@ -188,23 +190,19 @@ linux_ptrace_test_ret_to_nx (void)
+       return;
+     }
+-  errno = 0;
++  if (ptrace (PTRACE_GETREGS, child, (PTRACE_TYPE_ARG3) 0,
++            (PTRACE_TYPE_ARG4) &regs) < 0)
++    {
++      warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_GETREGS: %s"),
++             safe_strerror (errno));
++    }
+ #if defined __i386__
+-  l = ptrace (PTRACE_PEEKUSER, child, (PTRACE_TYPE_ARG3) (uintptr_t) (EIP * 4),
+-            (PTRACE_TYPE_ARG4) NULL);
++  pc = (gdb_byte *) (uintptr_t) regs[EIP];
+ #elif defined __x86_64__
+-  l = ptrace (PTRACE_PEEKUSER, child, (PTRACE_TYPE_ARG3) (uintptr_t) (RIP * 8),
+-            (PTRACE_TYPE_ARG4) NULL);
++  pc = (gdb_byte *) (uintptr_t) regs[RIP];
+ #else
+ # error "!__i386__ && !__x86_64__"
+ #endif
+-  if (errno != 0)
+-    {
+-      warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_PEEKUSER: %s"),
+-             safe_strerror (errno));
+-      return;
+-    }
+-  pc = (gdb_byte *) (uintptr_t) l;
+   kill (child, SIGKILL);
+   ptrace (PTRACE_KILL, child, (PTRACE_TYPE_ARG3) NULL,
+-- 
+1.7.1
+
+From e565c44e294111fdc2b84396917b0c4ffed916fb Mon Sep 17 00:00:00 2001
+From: Pedro Alves <palves@redhat.com>
+Date: Thu, 11 Aug 2016 12:03:18 +0100
+Subject: [PATCH] Fix fallout from gdb/20413's fix (x32: linux_ptrace_test_ret_to_nx: Cannot PTRACE_PEEKUSER)
+
+Fixes, on NIOS GNU/Linux:
+
+  In file included from
+  /scratch/mbilal/nois-lite/src/gdb-trunk/gdb/gdbserver/../nat/linux-ptrace.c:26:0:
+  /scratch/mbilal/nois-lite/src/gdb-trunk/gdb/gdbserver/../gregset.h:27:23:
+  error: unknown type name 'gregset_t'
+   #define GDB_GREGSET_T gregset_t
+                        ^
+
+Fix this by including sys/procfs.h directly.  We shouldn't really be
+including a gdb-only header in a gdb/nat/ file, anyway.  Whoops.
+
+diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c
+index 980ed53..f00f179 100644
+--- a/gdb/nat/linux-ptrace.c
++++ b/gdb/nat/linux-ptrace.c
+@@ -23,7 +23,7 @@
+ #include "buffer.h"
+ #include "gdb_wait.h"
+ #include "gdb_ptrace.h"
+-#include "gregset.h"
++#include <sys/procfs.h>
+ /* Stores the ptrace options supported by the running kernel.
+    A value of -1 means we did not check for features yet.  A value
+-- 
+1.7.1
+
index 946cc41691f06ba31befb42df9f7e3d295cc70a4..28e7767a60202650dd997ac2a15ee985d2055e42 100644 (file)
--- a/gdb.spec
+++ b/gdb.spec
@@ -21,7 +21,7 @@ Summary(zh_TW.UTF-8): [.-A開發]C和.$)B其.-A他語.$)B言的調試器
 %define                snap    20120926
 Name:          gdb
 Version:       7.11.1
-Release:       1
+Release:       2
 License:       GPL v3+
 Group:         Development/Debuggers
 Source0:       http://ftp.gnu.org/gnu/gdb/%{name}-%{version}.tar.xz
@@ -29,6 +29,10 @@ Source0:     http://ftp.gnu.org/gnu/gdb/%{name}-%{version}.tar.xz
 Source1:       http://www.mif.pg.gda.pl/homepages/ankry/man-PLD/%{name}-non-english-man-pages.tar.bz2
 # Source1-md5: 2e8a48939ae282c12bbacdd54e398247
 Source3:       %{name}-gstack.man
+# https://sourceware.org/bugzilla/show_bug.cgi?id=20287
+Patch0:                gdb-bug-20287.patch
+# https://sourceware.org/bugzilla/show_bug.cgi?id=20413
+Patch1:                gdb-bug-20413.patch
 Patch100:      gdb-6.6-buildid-locate.patch
 Patch101:      gdb-6.6-buildid-locate-solib-missing-ids.patch
 Patch102:      gdb-6.6-buildid-locate-rpm.patch
@@ -172,6 +176,9 @@ GDB w postaci biblioteki statycznej.
 %prep
 %setup -q
 
+%patch0 -p1
+%patch1 -p1
+
 # Files have `# <number> <file>' statements breaking VPATH / find-debuginfo.sh .
 rm -f gdb/ada-exp.c gdb/ada-lex.c gdb/c-exp.c gdb/cp-name-parser.c gdb/f-exp.c
 rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
This page took 0.085076 seconds and 4 git commands to generate.