diff options
author | Pedro Alves <palves@redhat.com> | 2016-07-26 19:35:40 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2016-07-26 19:35:40 +0100 |
commit | 9cf12d57c58a82cfe3e6fee26d1ea55dfe49f9c4 (patch) | |
tree | 93783c148aab34b618a4c1e1c5ca7bce39d0463b /gdb/amd64-linux-nat.c | |
parent | d0d4152fa5c87532bf05007def680b5a536e1827 (diff) | |
download | binutils-9cf12d57c58a82cfe3e6fee26d1ea55dfe49f9c4.zip binutils-9cf12d57c58a82cfe3e6fee26d1ea55dfe49f9c4.tar.gz binutils-9cf12d57c58a82cfe3e6fee26d1ea55dfe49f9c4.tar.bz2 |
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'.
Diffstat (limited to 'gdb/amd64-linux-nat.c')
-rw-r--r-- | gdb/amd64-linux-nat.c | 10 |
1 files changed, 5 insertions, 5 deletions
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, } -/* 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; |