From: Arkadiusz Miśkiewicz Date: Tue, 23 Aug 2016 17:15:05 +0000 (+0200) Subject: - rel 2; x32 fixes X-Git-Tag: auto/th/gdb-7.11.1-2 X-Git-Url: http://git.pld-linux.org/gitweb.cgi?a=commitdiff_plain;h=e33669644c312edf419b21e6383c4e9be0b95126;p=packages%2Fgdb.git - rel 2; x32 fixes --- diff --git a/gdb-bug-20287.patch b/gdb-bug-20287.patch new file mode 100644 index 0000000..e1da98a --- /dev/null +++ b/gdb-bug-20287.patch @@ -0,0 +1,634 @@ +From 9cf12d57c58a82cfe3e6fee26d1ea55dfe49f9c4 Mon Sep 17 00:00:00 2001 +From: Pedro Alves +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 ‘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. + +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; +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 index 0000000..f8763f9 --- /dev/null +++ b/gdb-bug-20413.patch @@ -0,0 +1,111 @@ +From 40c31709c6a51926fcb409611caa52b2da6515c0 Mon Sep 17 00:00:00 2001 +From: Pedro Alves +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) ®s) < 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 +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 + + /* 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 + diff --git a/gdb.spec b/gdb.spec index 946cc41..28e7767 100644 --- 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 `# ' 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