]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit - gdb/gdbserver/ChangeLog
Fix PR gdb/20287 - x32 and "gdb_static_assert (sizeof (nat_siginfo_t) == sizeof ...
authorPedro Alves <palves@redhat.com>
Tue, 26 Jul 2016 18:35:40 +0000 (19:35 +0100)
committerPedro Alves <palves@redhat.com>
Tue, 26 Jul 2016 18:35:40 +0000 (19:35 +0100)
commit9cf12d57c58a82cfe3e6fee26d1ea55dfe49f9c4
tree93783c148aab34b618a4c1e1c5ca7bce39d0463b
parentd0d4152fa5c87532bf05007def680b5a536e1827
Fix PR gdb/20287 - x32 and "gdb_static_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t))"

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 ‘never_defined_just_used_for_checking’ 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 ‘gdb_static_assert’
   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.

gdb/ChangeLog:
2016-07-26  Pedro Alves  <palves@redhat.com>

* amd64-linux-nat.c (amd64_linux_siginfo_fixup): Rename 'native'
parameter to 'ptrace'.
* nat/amd64-linux-siginfo.c (GDB_SI_SIZE): New define.
(nat_uptr_t): New an unsigned long.
(nat_clock_t): Remove attribute __aligned__.
(struct nat_timeval): Delete.
(nat_siginfo_t): Remove attribute __aligned__.
(ptrace_siginfo_t): Define.
(compat_siginfo_from_siginfo, siginfo_from_compat_siginfo)
(compat_x32_siginfo_from_siginfo)
(siginfo_from_compat_x32_siginfo): Make 'from' parameter const.
Convert through a ptrace_siginfo_t instead of a nat_siginfo_t.
Remove casts.
(amd64_linux_siginfo_fixup_common): Rename 'native' parameter to
'ptrace'.  Remove static assertions.
(top level): New static assertions.

gdb/gdbserver/ChangeLog:
2016-07-26  Pedro Alves  <palves@redhat.com>

* linux-x86-low.c (x86_siginfo_fixup): Rename 'native' parameter
to 'ptrace'.
gdb/ChangeLog
gdb/amd64-linux-nat.c
gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-x86-low.c
gdb/nat/amd64-linux-siginfo.c