public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH V4 3/6] Use linux_get_siginfo_type_with_fields for x86.
  2016-01-21 14:48 [PATCH V4 0/6] Intel MPX bound violation support Walfred Tedeschi
@ 2016-01-21 14:48 ` Walfred Tedeschi
  2016-01-21 14:49 ` [PATCH V4 5/6] Adaptation of siginfo fixup for the new bnd fields Walfred Tedeschi
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-21 14:48 UTC (permalink / raw)
  To: palves, eliz, brobecker; +Cc: gdb-patches, Walfred Tedeschi

Use linux_get_siginfo_type_with_fields for adding bound fields on
segmentation fault for i386/amd64 siginfo.

2016-01-15  Walfred Tedeschi  <walfred.tedeschi@intel.com>

gdb/ChangeLog:

	* linux-tdep.h (linux_get_siginfo_type_with_fields): Make extern.
	* linux-tdep.c (linux_get_siginfo_type_with_fields): Make extern.
	* i386-linux-tdep.h (x86_linux_get_siginfo_type): New
	function.
	* amd64-linux-tdep.c (amd64_linux_init_abi_common): Add
	x86_linux_get_siginfo_type for the amd64 abi.
	* i386-linux-tdep.c (x86_linux_get_siginfo_type): New
	Function.
	(i386_linux_init_abi): Add new function at the i386 ABI
	initialization.

---
 gdb/amd64-linux-tdep.c | 2 ++
 gdb/i386-linux-tdep.c  | 8 ++++++++
 gdb/i386-linux-tdep.h  | 3 +++
 gdb/linux-tdep.c       | 2 +-
 gdb/linux-tdep.h       | 4 ++++
 5 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index b948ea7..21bcd99 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -1838,6 +1838,8 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_process_record (gdbarch, i386_process_record);
   set_gdbarch_process_record_signal (gdbarch, amd64_linux_record_signal);
+
+  set_gdbarch_get_siginfo_type (gdbarch, x86_linux_get_siginfo_type);
 }
 
 static void
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 1e491e7..af39e78 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -656,6 +656,12 @@ i386_linux_supply_xstateregset (const struct regset *regset,
   i387_supply_xsave (regcache, regnum, xstateregs);
 }
 
+struct type *
+x86_linux_get_siginfo_type (struct gdbarch *gdbarch)
+{
+  return linux_get_siginfo_type_with_fields (gdbarch, LINUX_SIGINFO_FIELD_ADDR_BND);
+}
+
 /* Similar to i386_collect_fpregset, but use XSAVE extended state.  */
 
 static void
@@ -994,6 +1000,8 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_I386);
   set_gdbarch_get_syscall_number (gdbarch,
                                   i386_linux_get_syscall_number);
+
+  set_gdbarch_get_siginfo_type (gdbarch, x86_linux_get_siginfo_type);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h
index ee6abff..f8e0074 100644
--- a/gdb/i386-linux-tdep.h
+++ b/gdb/i386-linux-tdep.h
@@ -72,4 +72,7 @@ extern struct target_desc *tdesc_i386_avx512_linux;
 
 extern int i386_linux_gregset_reg_offset[];
 
+/* Returns x86 siginfo type with extra fields.  */
+extern struct type *x86_get_siginfo_type_with_fields (struct gdbarch *gdbarch);
+
 #endif /* i386-linux-tdep.h */
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 48bed11..a49057f 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -246,7 +246,7 @@ get_linux_inferior_data (void)
 /* This function is suitable for architectures that
    extend/override the standard siginfo in an specific way.  */
 
-static struct type *
+struct type *
 linux_get_siginfo_type_with_fields (struct gdbarch *gdbarch,
 				    linux_siginfo_extra_fields extra_fields)
 {
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index 98a17fa..5fcd266 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -34,6 +34,10 @@ enum linux_siginfo_extra_field_values
 /* Defines a type for the values defined in linux_siginfo_extra_field_values.  */
 DEF_ENUM_FLAGS_TYPE (enum linux_siginfo_extra_field_values, linux_siginfo_extra_fields);
 
+/* Return the siginfo type with additional fields.  */
+struct type *linux_get_siginfo_type_with_fields (struct gdbarch *gdbarch,
+						 linux_siginfo_extra_fields);
+
 typedef char *(*linux_collect_thread_registers_ftype) (const struct regcache *,
 						       ptid_t,
 						       bfd *, char *, int *,
-- 
2.1.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH V4 0/6]  Intel MPX bound violation support
@ 2016-01-21 14:48 Walfred Tedeschi
  2016-01-21 14:48 ` [PATCH V4 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-21 14:48 UTC (permalink / raw)
  To: palves, eliz, brobecker; +Cc: gdb-patches, Walfred Tedeschi

Intel MPX bound violation support.

First 5 patches of the series are preparation for the
bound violation handler.

Preparation:

Fixup implementation for GDB and gdbserver of siginfo 
types for x32 and 32bits inferior running on 64bits are merged.

It was added a simple way to add fields in the
siginfo structure for all architectures.

For i386/amd64 the dependency on the siginfo where
GDB/gdbserver for the usage and display was eliminated.
Now GDB descriptions of this type are enough for display

Bound violation information can be seen in the last commit of
the series.


From V3 to V4:

* Changed changelog and added Pedro's comments on 1/6.
* Added Pedro's feedback on 3/6.
* News is added into 6/6.

Thanks for the review and regards,
-Fred 


Walfred Tedeschi (6):
  Merge gdb and gdbserver implementations for siginfo
  Prepararion for new siginfo on Linux.
  Use linux_get_siginfo_type_with_fields for x86.
  Add bound related fields to the siginfo structure.
  Adaptation of siginfo fixup for the new bnd fields.
  Intel MPX bound violation handling.

 gdb/Makefile.in                                 |   6 +-
 gdb/NEWS                                        |  15 +
 gdb/amd64-linux-nat.c                           | 431 +-----------------
 gdb/amd64-linux-tdep.c                          |   4 +
 gdb/config/i386/linux64.mh                      |   2 +-
 gdb/doc/gdb.texinfo                             |  51 +++
 gdb/gdbarch.c                                   |  32 ++
 gdb/gdbarch.h                                   |  11 +
 gdb/gdbarch.sh                                  |   6 +
 gdb/gdbserver/Makefile.in                       |   3 +
 gdb/gdbserver/configure.srv                     |   4 +-
 gdb/gdbserver/linux-x86-low.c                   | 423 +----------------
 gdb/i386-linux-tdep.c                           |  53 +++
 gdb/i386-linux-tdep.h                           |   8 +
 gdb/i386-tdep.c                                 |   4 +-
 gdb/i386-tdep.h                                 |   2 +
 gdb/infrun.c                                    |  34 ++
 gdb/linux-tdep.c                                |  34 +-
 gdb/linux-tdep.h                                |  14 +
 gdb/nat/amd64-linux-siginfo.c                   | 574 ++++++++++++++++++++++++
 gdb/nat/amd64-linux-siginfo.h                   |  56 +++
 gdb/testsuite/gdb.arch/i386-mpx-sigsegv.c       | 120 +++++
 gdb/testsuite/gdb.arch/i386-mpx-sigsegv.exp     |  86 ++++
 gdb/testsuite/gdb.arch/i386-mpx-simple_segv.c   |  66 +++
 gdb/testsuite/gdb.arch/i386-mpx-simple_segv.exp | 129 ++++++
 25 files changed, 1316 insertions(+), 852 deletions(-)
 create mode 100644 gdb/nat/amd64-linux-siginfo.c
 create mode 100644 gdb/nat/amd64-linux-siginfo.h
 create mode 100644 gdb/testsuite/gdb.arch/i386-mpx-sigsegv.c
 create mode 100644 gdb/testsuite/gdb.arch/i386-mpx-sigsegv.exp
 create mode 100644 gdb/testsuite/gdb.arch/i386-mpx-simple_segv.c
 create mode 100644 gdb/testsuite/gdb.arch/i386-mpx-simple_segv.exp

-- 
2.1.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH V4 2/6] Prepararion for new siginfo on Linux.
  2016-01-21 14:48 [PATCH V4 0/6] Intel MPX bound violation support Walfred Tedeschi
                   ` (4 preceding siblings ...)
  2016-01-21 14:49 ` [PATCH V4 6/6] Intel MPX bound violation handling Walfred Tedeschi
@ 2016-01-21 14:49 ` Walfred Tedeschi
  2016-01-21 15:05   ` Pedro Alves
  5 siblings, 1 reply; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-21 14:49 UTC (permalink / raw)
  To: palves, eliz, brobecker; +Cc: gdb-patches, Walfred Tedeschi

First add new structure and function to allow architecture customization
for the siginfo structure.

2016-01-15  Walfred Tedeschi  <walfred.tedeschi@intel.com>

gdb/ChangeLog:

	* linux-tdep.h (linux_siginfo_extra_field_values): New enum values.
	(linux_siginfo_extra_fields): New enum type.
	* linux-tdep.c (linux_get_siginfo_type_with_fields): New function.
	(linux_get_siginfo_type): Use new function.

---
 gdb/linux-tdep.c | 16 +++++++++++++---
 gdb/linux-tdep.h | 10 ++++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 29f5f3c..48bed11 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -243,11 +243,12 @@ get_linux_inferior_data (void)
   return info;
 }
 
-/* This function is suitable for architectures that don't
-   extend/override the standard siginfo structure.  */
+/* This function is suitable for architectures that
+   extend/override the standard siginfo in an specific way.  */
 
 static struct type *
-linux_get_siginfo_type (struct gdbarch *gdbarch)
+linux_get_siginfo_type_with_fields (struct gdbarch *gdbarch,
+				    linux_siginfo_extra_fields extra_fields)
 {
   struct linux_gdbarch_data *linux_gdbarch_data;
   struct type *int_type, *uint_type, *long_type, *void_ptr_type;
@@ -364,6 +365,15 @@ linux_get_siginfo_type (struct gdbarch *gdbarch)
   return siginfo_type;
 }
 
+/* This function is suitable for architectures that don't
+   extend/override the standard siginfo structure.  */
+
+static struct type *
+linux_get_siginfo_type (struct gdbarch *gdbarch)
+{
+  return linux_get_siginfo_type_with_fields (gdbarch, 0);
+}
+
 /* Return true if the target is running on uClinux instead of normal
    Linux kernel.  */
 
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index 328c7f0..98a17fa 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -24,6 +24,16 @@
 
 struct regcache;
 
+/* Enum used to define which kind of siginfo is used by the architecture.  */
+enum linux_siginfo_extra_field_values
+{
+  /* Add bound fields into the segmentation fault fields.  */
+  LINUX_SIGINFO_FIELD_ADDR_BND = 1
+};
+
+/* Defines a type for the values defined in linux_siginfo_extra_field_values.  */
+DEF_ENUM_FLAGS_TYPE (enum linux_siginfo_extra_field_values, linux_siginfo_extra_fields);
+
 typedef char *(*linux_collect_thread_registers_ftype) (const struct regcache *,
 						       ptid_t,
 						       bfd *, char *, int *,
-- 
2.1.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH V4 5/6] Adaptation of siginfo fixup for the new bnd fields.
  2016-01-21 14:48 [PATCH V4 0/6] Intel MPX bound violation support Walfred Tedeschi
  2016-01-21 14:48 ` [PATCH V4 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
@ 2016-01-21 14:49 ` Walfred Tedeschi
  2016-01-21 14:49 ` [PATCH V4 1/6] Merge gdb and gdbserver implementations for siginfo Walfred Tedeschi
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-21 14:49 UTC (permalink / raw)
  To: palves, eliz, brobecker; +Cc: gdb-patches, Walfred Tedeschi

New bnds fields will be always present for x86 architecture.
Fixup for compatibility layer 32bits has to be fixed.

It was added the nat_siginfo to serving as intermediate step
between kernel provided siginfo and the fix up routine.

When executing compat_siginfo_from_siginfo or
compat_x32_siginfo_from_siginfo first the buffer read from the kernel are
converted into the nat_signfo for homogenization, then the fields of
nat_siginfo are use to set the compat and compat_x32 siginfo structures.

When executing  siginfo_from_compat_siginfo or
siginfo_from_compat_x32_siginfo the process happens in oposite order.

In doing this the fixups become more independent of the system underneath.

Caveat: No support for MPX on x32.

2015-01-15  Walfred Tedeschi  <walfred.tedeschi@intel.com>

gdb/ChangeLog:

	* amd64-linux-siginfo.c (nat_siginfo_t, nat_sigval_t, nat_timeval):
	New types.
	(compat_siginfo): New bound fields added.
	(compat_x32_siginfo): New field added.
	(cpt_si_addr_lsb): New define.
	(compat_siginfo_from_siginfo): Use nat_siginfo.
	(siginfo_from_compat_siginfo): Use nat_siginfo.
	(compat_x32_siginfo_from_siginfo): Likewise.
	(siginfo_from_compat_x32_siginfo): Likewise.

---
 gdb/nat/amd64-linux-siginfo.c | 312 ++++++++++++++++++++++++++++--------------
 gdb/nat/amd64-linux-siginfo.h |  16 ++-
 2 files changed, 226 insertions(+), 102 deletions(-)

diff --git a/gdb/nat/amd64-linux-siginfo.c b/gdb/nat/amd64-linux-siginfo.c
index 36b5505..f3e190c 100644
--- a/gdb/nat/amd64-linux-siginfo.c
+++ b/gdb/nat/amd64-linux-siginfo.c
@@ -21,6 +21,93 @@
 #include "common-defs.h"
 #include "amd64-linux-siginfo.h"
 
+/* These types below (native_*) define a siginfo type that is layout
+   the most complete siginfo available for the architecture.  */
+
+typedef int nat_int_t;
+typedef void* 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;
+};
+
+typedef union nat_sigval
+{
+  nat_int_t sival_int;
+  nat_uptr_t sival_ptr;
+} nat_sigval_t;
+
+typedef struct nat_siginfo
+{
+  int si_signo;
+  int si_errno;
+  int si_code;
+
+  union
+  {
+    int _pad[((128 / sizeof (int)) - 4)];
+    /* kill() */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+    } _kill;
+
+    /* POSIX.1b timers */
+    struct
+    {
+      nat_timer_t _tid;
+      int _overrun;
+      nat_sigval_t _sigval;
+    } _timer;
+
+    /* POSIX.1b signals */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+      nat_sigval_t _sigval;
+    } _rt;
+
+    /* SIGCHLD */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+      int _status;
+      nat_clock_t _utime;
+      nat_clock_t _stime;
+    } _sigchld;
+
+    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+    struct
+    {
+      nat_uptr_t _addr;
+      short int _addr_lsb;
+      struct
+      {
+	nat_uptr_t _lower;
+	nat_uptr_t _upper;
+      } si_addr_bnd;
+    } _sigfault;
+
+    /* SIGPOLL */
+    struct
+    {
+      int _band;
+      int _fd;
+    } _sigpoll;
+  } _sifields;
+} nat_siginfo_t __attribute__ ((__aligned__ (8)));
+
 /* These types below (compat_*) define a siginfo type that is layout
    compatible with the siginfo type exported by the 32-bit userspace
    support.  */
@@ -91,6 +178,12 @@ typedef struct compat_siginfo
     struct
     {
       unsigned int _addr;
+      short int _addr_lsb;
+      struct
+      {
+	unsigned int _lower;
+	unsigned int _upper;
+      } si_addr_bnd;
     } _sigfault;
 
     /* SIGPOLL */
@@ -152,6 +245,7 @@ typedef struct compat_x32_siginfo
     struct
     {
       unsigned int _addr;
+      unsigned int _addr_lsb;
     } _sigfault;
 
     /* SIGPOLL */
@@ -174,6 +268,7 @@ typedef struct compat_x32_siginfo
 #define cpt_si_stime _sifields._sigchld._stime
 #define cpt_si_ptr _sifields._rt._sigval.sival_ptr
 #define cpt_si_addr _sifields._sigfault._addr
+#define cpt_si_addr_lsb _sifields._sigfault._addr_lsb
 #define cpt_si_band _sifields._sigpoll._band
 #define cpt_si_fd _sifields._sigpoll._fd
 
@@ -192,54 +287,58 @@ typedef struct compat_x32_siginfo
 static void
 compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
 {
+  nat_siginfo_t from_nat;
+
+  gdb_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+  memcpy (&from_nat, from, sizeof (from_nat));
   memset (to, 0, sizeof (*to));
 
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
+  to->si_signo = from_nat.si_signo;
+  to->si_errno = from_nat.si_errno;
+  to->si_code = from_nat.si_code;
 
   if (to->si_code == SI_TIMER)
     {
-      to->cpt_si_timerid = from->si_timerid;
-      to->cpt_si_overrun = from->si_overrun;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+      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;
     }
   else if (to->si_code == SI_USER)
     {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
+      to->cpt_si_pid = from_nat.cpt_si_pid;
+      to->cpt_si_uid = from_nat.cpt_si_uid;
     }
   else if (to->si_code < 0)
     {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+      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;
     }
   else
     {
       switch (to->si_signo)
 	{
 	case SIGCHLD:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_status = from->si_status;
-	  to->cpt_si_utime = from->si_utime;
-	  to->cpt_si_stime = from->si_stime;
+	  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;
 	  break;
 	case SIGILL:
 	case SIGFPE:
 	case SIGSEGV:
 	case SIGBUS:
-	  to->cpt_si_addr = (intptr_t) from->si_addr;
+	  to->cpt_si_addr = (intptr_t) from_nat.cpt_si_addr;
 	  break;
 	case SIGPOLL:
-	  to->cpt_si_band = from->si_band;
-	  to->cpt_si_fd = from->si_fd;
+	  to->cpt_si_band = from_nat.cpt_si_band;
+	  to->cpt_si_fd = from_nat.cpt_si_fd;
 	  break;
 	default:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
+	  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;
 	  break;
 	}
     }
@@ -250,57 +349,62 @@ compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
 static void
 siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
 {
-  memset (to, 0, sizeof (*to));
+  nat_siginfo_t to_nat;
 
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
+  gdb_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+  memset (&to_nat, 0, sizeof (to_nat));
 
-  if (to->si_code == SI_TIMER)
+  to_nat.si_signo = from->si_signo;
+  to_nat.si_errno = from->si_errno;
+  to_nat.si_code = from->si_code;
+
+  if (to_nat.si_code == SI_TIMER)
     {
-      to->si_timerid = from->cpt_si_timerid;
-      to->si_overrun = from->cpt_si_overrun;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+      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;
     }
-  else if (to->si_code == SI_USER)
+  else if (to_nat.si_code == SI_USER)
     {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
+      to_nat.cpt_si_pid = from->cpt_si_pid;
+      to_nat.cpt_si_uid = from->cpt_si_uid;
     }
-  if (to->si_code < 0)
+  if (to_nat.si_code < 0)
     {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+      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;
     }
   else
     {
-      switch (to->si_signo)
+      switch (to_nat.si_signo)
 	{
 	case SIGCHLD:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_status = from->cpt_si_status;
-	  to->si_utime = from->cpt_si_utime;
-	  to->si_stime = from->cpt_si_stime;
+	  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;
 	  break;
 	case SIGILL:
 	case SIGFPE:
 	case SIGSEGV:
 	case SIGBUS:
-	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
+	  to_nat.cpt_si_addr = (void *) (intptr_t) from->cpt_si_addr;
+	  to_nat.cpt_si_addr_lsb = (short) from->cpt_si_addr_lsb;
 	  break;
 	case SIGPOLL:
-	  to->si_band = from->cpt_si_band;
-	  to->si_fd = from->cpt_si_fd;
+	  to_nat.cpt_si_band = from->cpt_si_band;
+	  to_nat.cpt_si_fd = from->cpt_si_fd;
 	  break;
 	default:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
+	  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;
 	  break;
 	}
     }
+  memcpy (to, &to_nat, sizeof (to_nat));
 }
 
 /*  Convert the system provided siginfo into compatible x32 siginfo.  */
@@ -309,56 +413,60 @@ static void
 compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
 				 siginfo_t *from)
 {
+  nat_siginfo_t from_nat;
+
+  gdb_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+  memcpy (&from_nat, from, sizeof (from_nat));
   memset (to, 0, sizeof (*to));
 
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
+  to->si_signo = from_nat.si_signo;
+  to->si_errno = from_nat.si_errno;
+  to->si_code = from_nat.si_code;
 
   if (to->si_code == SI_TIMER)
     {
-      to->cpt_si_timerid = from->si_timerid;
-      to->cpt_si_overrun = from->si_overrun;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+      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;
     }
   else if (to->si_code == SI_USER)
     {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
+      to->cpt_si_pid = from_nat.cpt_si_pid;
+      to->cpt_si_uid = from_nat.cpt_si_uid;
     }
   else if (to->si_code < 0)
     {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+      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;
     }
   else
     {
       switch (to->si_signo)
 	{
 	case SIGCHLD:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_status = from->si_status;
-	  memcpy (&to->cpt_si_utime, &from->si_utime,
+	  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,
 		  sizeof (to->cpt_si_utime));
-	  memcpy (&to->cpt_si_stime, &from->si_stime,
+	  memcpy (&to->cpt_si_stime, &from_nat.cpt_si_stime,
 		  sizeof (to->cpt_si_stime));
 	  break;
 	case SIGILL:
 	case SIGFPE:
 	case SIGSEGV:
 	case SIGBUS:
-	  to->cpt_si_addr = (intptr_t) from->si_addr;
+	  to->cpt_si_addr = (intptr_t) from_nat.cpt_si_addr;
 	  break;
 	case SIGPOLL:
-	  to->cpt_si_band = from->si_band;
-	  to->cpt_si_fd = from->si_fd;
+	  to->cpt_si_band = from_nat.cpt_si_band;
+	  to->cpt_si_fd = from_nat.cpt_si_fd;
 	  break;
 	default:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
+	  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;
 	  break;
 	}
     }
@@ -369,59 +477,63 @@ static void
 siginfo_from_compat_x32_siginfo (siginfo_t *to,
 				 compat_x32_siginfo_t *from)
 {
-  memset (to, 0, sizeof (*to));
+  nat_siginfo_t to_nat;
 
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
+  gdb_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
+  memset (&to_nat, 0, sizeof (to_nat));
 
-  if (to->si_code == SI_TIMER)
+  to_nat.si_signo = from->si_signo;
+  to_nat.si_errno = from->si_errno;
+  to_nat.si_code = from->si_code;
+
+  if (to_nat.si_code == SI_TIMER)
     {
-      to->si_timerid = from->cpt_si_timerid;
-      to->si_overrun = from->cpt_si_overrun;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+      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;
     }
-  else if (to->si_code == SI_USER)
+  else if (to_nat.si_code == SI_USER)
     {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
+      to_nat.cpt_si_pid = from->cpt_si_pid;
+      to_nat.cpt_si_uid = from->cpt_si_uid;
     }
-  if (to->si_code < 0)
+  if (to_nat.si_code < 0)
     {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+      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;
     }
   else
     {
-      switch (to->si_signo)
+      switch (to_nat.si_signo)
 	{
 	case SIGCHLD:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_status = from->cpt_si_status;
-	  memcpy (&to->si_utime, &from->cpt_si_utime,
-		  sizeof (to->si_utime));
-	  memcpy (&to->si_stime, &from->cpt_si_stime,
-		  sizeof (to->si_stime));
+	  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));
 	  break;
 	case SIGILL:
 	case SIGFPE:
 	case SIGSEGV:
 	case SIGBUS:
-	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
+	  to_nat.cpt_si_addr = (void *) (intptr_t) from->cpt_si_addr;
 	  break;
 	case SIGPOLL:
-	  to->si_band = from->cpt_si_band;
-	  to->si_fd = from->cpt_si_fd;
+	  to_nat.cpt_si_band = from->cpt_si_band;
+	  to_nat.cpt_si_fd = from->cpt_si_fd;
 	  break;
 	default:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
+	  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;
 	  break;
 	}
     }
+  memcpy (to, &to_nat, sizeof (to_nat));
 }
 
 /* Convert a native/host siginfo object, into/from the siginfo in the
diff --git a/gdb/nat/amd64-linux-siginfo.h b/gdb/nat/amd64-linux-siginfo.h
index a396966..5b29cbe 100644
--- a/gdb/nat/amd64-linux-siginfo.h
+++ b/gdb/nat/amd64-linux-siginfo.h
@@ -20,12 +20,24 @@
 #ifndef AMD64_LINUX_SIGINFO_H
 #define AMD64_LINUX_SIGINFO_H 1
 
-
 /* When GDB is built as a 64-bit application on Linux, the
    PTRACE_GETSIGINFO data is always presented in 64-bit layout.  Since
    debugging a 32-bit inferior with a 64-bit GDB should look the same
    as debugging it with a 32-bit GDB, we do the 32-bit <-> 64-bit
-   conversion in-place ourselves.  */
+   conversion in-place ourselves.
+   In other to make this conversion independent of the system where gdb
+   is compiled the most complete version of the siginfo, named as native
+   siginfo, is used internally as an intermediate step.
+
+   Conversion using nat_siginfo is exemplified below:
+   compat_siginfo_from_siginfo or compat_x32_siginfo_from_siginfo
+
+      buffer (from the kernel) -> nat_siginfo -> 32 / X32 siginfo
+
+   siginfo_from_compat_x32_siginfo or siginfo_from_compat_siginfo
+
+     32 / X32 siginfo -> nat_siginfo -> buffer (to the kernel)  */
+
 
 /* Kind of siginfo fixup to be performed.  */
 
-- 
2.1.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH V4 6/6] Intel MPX bound violation handling.
  2016-01-21 14:48 [PATCH V4 0/6] Intel MPX bound violation support Walfred Tedeschi
                   ` (3 preceding siblings ...)
  2016-01-21 14:49 ` [PATCH V4 4/6] Add bound related fields to the siginfo structure Walfred Tedeschi
@ 2016-01-21 14:49 ` Walfred Tedeschi
  2016-01-21 16:23   ` Eli Zaretskii
  2016-01-21 14:49 ` [PATCH V4 2/6] Prepararion for new siginfo on Linux Walfred Tedeschi
  5 siblings, 1 reply; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-21 14:49 UTC (permalink / raw)
  To: palves, eliz, brobecker; +Cc: gdb-patches, Walfred Tedeschi

With Intel Memory Protection Extensions it was introduced the concept of
boundary violation.  A boundary violations is presented to the inferior as
a segmentation fault having SIGCODE 3.  This patch adds a
handler for a boundary violation extending the information displayed
when a bound violation is presented to the inferior.  In the stop mode
case the debugger will also display the kind of violation: "upper" or
"lower", bounds and the address accessed.
On no stop mode the information will still remain unchanged.  Additional
information about bound violations are not meaningful in that case user
does not know the line in which violation occurred as well.

When the segmentation fault handler is stop mode the out puts will be
changed as exemplified below.

The usual output of a segfault is:
Program received signal SIGSEGV, Segmentation fault
0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
68        value = *(p + len);

In case it is a bound violation it will be presented as:
Program received signal SIGSEGV, Segmentation fault
upper bound violation - bounds {lbound = 0x603010, ubound = 0x603023}
accessing 0x60302f.
0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
68        value = *(p + len);

In mi mode the output of a segfault is:
*stopped,reason="signal-received",signal-name="SIGSEGV",
signal-meaning="Segmentation fault", frame={addr="0x0000000000400d7c",
func="upper",args=[{name="p", value="0x603010"},{name="a",value="0x603030"}
,{name="b",value="0x603050"}, {name="c",value="0x603070"},
{name="d",value="0x603090"},{name="len",value="7"}],
file="i386-mpx-sigsegv.c",fullname="i386-mpx-sigsegv.c",line="68"},
thread-id="1",stopped-threads="all",core="6"

in the case of a bound violation:
*stopped,reason="signal-received",signal-name="SIGSEGV",
signal-meaning="Segmentation fault",
sigcode-meaning="upper bound violation",
lower-bound="0x603010",upper-bound="0x603023",bound-access="0x60302f",
frame={addr="0x0000000000400d7c",func="upper",args=[{name="p",
value="0x603010"},{name="a",value="0x603030"},{name="b",value="0x603050"},
{name="c",value="0x603070"},{name="d",value="0x603090"},
{name="len",value="7"}],file="i386-mpx-sigsegv.c",
fullname="i386-mpx-sigsegv.c",line="68"},thread-id="1",
stopped-threads="all",core="6"

2016-01-15  Walfred Tedeschi  <walfred.tedeschi@intel.com>

gdb/ChangeLog:

	* NEWS: Add entry for bound violation.
	* amd64-linux-tdep.c (amd64_linux_init_abi_common):
	Add handler for bound violation.
	* gdbarch.sh (bound_violation_handler): New.
	* gdbarch.c: Regenerate.
	* gdbarch.h: Regenerate.
	* i386-linux-tdep.c (i386_mpx_bound_violation_handler): New.
	(i386_linux_init_abi): Use i386_mpx_bound_violation_handler.
	* i386-linux-tdep.h (i386_mpx_bound_violation_handler) New.
	* i386-tdep.c (i386_mpx_enabled): Add as external.
	* i386-tdep.c (i386_mpx_enabled): Add as external.
	* infrun.c (handle_segmentation_faults): New function.
	(print_signal_received_reason): Use handle_segmentation_faults.
	(normal_stop): Change order of observer in order to have the
	inferior stopped for evaluation.

gdb/testsuite/ChangeLog:

	* gdb.arch/i386-mpx-sigsegv.c: New.
	* gdb.arch/i386-mpx-sigsegv.exp: New.
	* gdb.arch/i386-mpx-simple_segv.c: New.
	* gdb.arch/i386-mpx-simple_segv.exp: New.

gdb/doc/ChangeLog:

	* gdb.texinfo (Intel Memory Protection Extensions): Add bound
	violation handler.


Conflicts:
	gdb/amd64-linux-tdep.c
	gdb/i386-linux-tdep.c
---
 gdb/NEWS                                        |  15 +++
 gdb/amd64-linux-tdep.c                          |   2 +
 gdb/doc/gdb.texinfo                             |  51 ++++++++++
 gdb/gdbarch.c                                   |  32 ++++++
 gdb/gdbarch.h                                   |  11 ++
 gdb/gdbarch.sh                                  |   6 ++
 gdb/i386-linux-tdep.c                           |  45 +++++++++
 gdb/i386-linux-tdep.h                           |   5 +
 gdb/i386-tdep.c                                 |   4 +-
 gdb/i386-tdep.h                                 |   2 +
 gdb/infrun.c                                    |  34 +++++++
 gdb/testsuite/gdb.arch/i386-mpx-sigsegv.c       | 120 ++++++++++++++++++++++
 gdb/testsuite/gdb.arch/i386-mpx-sigsegv.exp     |  86 ++++++++++++++++
 gdb/testsuite/gdb.arch/i386-mpx-simple_segv.c   |  66 ++++++++++++
 gdb/testsuite/gdb.arch/i386-mpx-simple_segv.exp | 129 ++++++++++++++++++++++++
 15 files changed, 605 insertions(+), 3 deletions(-)
 create mode 100644 gdb/testsuite/gdb.arch/i386-mpx-sigsegv.c
 create mode 100644 gdb/testsuite/gdb.arch/i386-mpx-sigsegv.exp
 create mode 100644 gdb/testsuite/gdb.arch/i386-mpx-simple_segv.c
 create mode 100644 gdb/testsuite/gdb.arch/i386-mpx-simple_segv.exp

diff --git a/gdb/NEWS b/gdb/NEWS
index d9cbb80..d738874 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,21 @@
 
 *** Changes since GDB 7.10
 
+* Intel MPX boud violation handler.
+
+   A boundary violations is presented to the inferior as
+   a segmentation fault having SIGCODE 3. In this case
+   GDB  displays also the kind of violation (upper or lower), 
+   bounds, poiter value and the memory accessed, besides displaying
+   the usual signal received and code location report.
+
+   As exemplified below:
+   Program received signal SIGSEGV, Segmentation fault
+   upper bound violation - bounds {lbound = 0x603010, ubound = 0x603023}
+   accessing 0x60302f.
+   0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
+   c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
+
 * Per-inferior thread numbers
 
   Thread numbers are now per inferior instead of global.  If you're
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 21bcd99..8af15c4 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -1840,6 +1840,8 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_process_record_signal (gdbarch, amd64_linux_record_signal);
 
   set_gdbarch_get_siginfo_type (gdbarch, x86_linux_get_siginfo_type);
+  set_gdbarch_bound_violation_handler(gdbarch,
+                                      i386_mpx_bound_violation_handler);
 }
 
 static void
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 7da31c8..91add58 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -22267,6 +22267,57 @@ whose bounds are to be changed, @var{lbound} and @var{ubound} are new values
 for lower and upper bounds respectively.
 @end table
 
+
+A boundary violation is presented to the inferior as
+a segmentation fault having SIGCODE 3. @value{GDBN} may display additional
+information is displayed in this case.  On @code{STOP} mode
+@value{GDBN} will also display the kind of violation: "upper" or
+"lower", bounds, pointer value and the address accessed.
+On @code{NOSTOP} no additional information will be presented.
+
+The usual output of a segfault is:
+@smallexample
+Program received signal SIGSEGV, Segmentation fault
+0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
+c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
+68        value = *(p + len);
+@end smallexample
+
+In case it is a bound violation it will be presented as:
+@smallexample
+Program received signal SIGSEGV, Segmentation fault
+upper bound violation - bounds @{lbound = 0x603010, ubound = 0x603023@}
+accessing 0x60302f.
+0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
+c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
+68        value = *(p + len);
+@end smallexample
+
+@sc{gdb/mi} is also taken into account, the output of a segmentation fault is:
+@smallexample
+*stopped,reason="signal-received",signal-name="SIGSEGV",
+signal-meaning="Segmentation fault", frame=@{addr="0x0000000000400d7c",
+func="upper",args=[@{name="p", value="0x603010"@},@{name="a",value="0x603030"@}
+,@{name="b",value="0x603050"@}, @{name="c",value="0x603070"@},
+@{name="d",value="0x603090"@},@{name="len",value="7"@}],
+file="i386-mpx-sigsegv.c",fullname="i386-mpx-sigsegv.c",line="68"@},
+thread-id="1",stopped-threads="all",core="6"
+@end smallexample
+
+in case of a bound violation it will be presented as:
+@smallexample
+*stopped,reason="signal-received",signal-name="SIGSEGV",
+signal-meaning="Segmentation fault",
+sigcode-meaning="upper bound violation",
+lower-bound="0x603010",upper-bound="0x603023",bound-access="0x60302f",
+frame=@{addr="0x0000000000400d7c",func="upper",args=[@{name="p",
+value="0x603010"@},@{name="a",value="0x603030"@},@{name="b",value="0x603050"@},
+@{name="c",value="0x603070"@},@{name="d",value="0x603090"@},
+@{name="len",value="7"@}],file="i386-mpx-sigsegv.c",
+fullname="i386-mpx-sigsegv.c",line="68"@},thread-id="1",
+stopped-threads="all",core="6"
+@end smallexample
+
 @node Alpha
 @subsection Alpha
 
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index d45af1a..f7fef25 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -189,6 +189,7 @@ struct gdbarch
   int num_pseudo_regs;
   gdbarch_ax_pseudo_register_collect_ftype *ax_pseudo_register_collect;
   gdbarch_ax_pseudo_register_push_stack_ftype *ax_pseudo_register_push_stack;
+  gdbarch_bound_violation_handler_ftype *bound_violation_handler;
   int sp_regnum;
   int pc_regnum;
   int ps_regnum;
@@ -531,6 +532,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of num_pseudo_regs, invalid_p == 0 */
   /* Skip verify of ax_pseudo_register_collect, has predicate.  */
   /* Skip verify of ax_pseudo_register_push_stack, has predicate.  */
+  /* Skip verify of bound_violation_handler, has predicate.  */
   /* Skip verify of sp_regnum, invalid_p == 0 */
   /* Skip verify of pc_regnum, invalid_p == 0 */
   /* Skip verify of ps_regnum, invalid_p == 0 */
@@ -773,6 +775,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: bits_big_endian = %s\n",
                       plongest (gdbarch->bits_big_endian));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_bound_violation_handler_p() = %d\n",
+                      gdbarch_bound_violation_handler_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: bound_violation_handler = <%s>\n",
+                      host_address_to_string (gdbarch->bound_violation_handler));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: breakpoint_from_pc = <%s>\n",
                       host_address_to_string (gdbarch->breakpoint_from_pc));
   fprintf_unfiltered (file,
@@ -1986,6 +1994,30 @@ set_gdbarch_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
 }
 
 int
+gdbarch_bound_violation_handler_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->bound_violation_handler != NULL;
+}
+
+void
+gdbarch_bound_violation_handler (struct gdbarch *gdbarch, struct ui_out *uiout)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->bound_violation_handler != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_bound_violation_handler called\n");
+  gdbarch->bound_violation_handler (gdbarch, uiout);
+}
+
+void
+set_gdbarch_bound_violation_handler (struct gdbarch *gdbarch,
+                                     gdbarch_bound_violation_handler_ftype bound_violation_handler)
+{
+  gdbarch->bound_violation_handler = bound_violation_handler;
+}
+
+int
 gdbarch_sp_regnum (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 3c16af2..eb5de0d 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -63,6 +63,7 @@ struct ravenscar_arch_ops;
 struct elf_internal_linux_prpsinfo;
 struct mem_range;
 struct syscalls_info;
+struct ui_out;
 
 #include "regcache.h"
 
@@ -299,6 +300,16 @@ typedef int (gdbarch_ax_pseudo_register_push_stack_ftype) (struct gdbarch *gdbar
 extern int gdbarch_ax_pseudo_register_push_stack (struct gdbarch *gdbarch, struct agent_expr *ax, int reg);
 extern void set_gdbarch_ax_pseudo_register_push_stack (struct gdbarch *gdbarch, gdbarch_ax_pseudo_register_push_stack_ftype *ax_pseudo_register_push_stack);
 
+/* Function called when a segmentation fault signal is received by the inferior,
+   having SIGCODE 3 (SIG_CODE_BOUNDARY_FAULT).
+   UIOUT is the output stream where the handler will place information. */
+
+extern int gdbarch_bound_violation_handler_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_bound_violation_handler_ftype) (struct gdbarch *gdbarch, struct ui_out *uiout);
+extern void gdbarch_bound_violation_handler (struct gdbarch *gdbarch, struct ui_out *uiout);
+extern void set_gdbarch_bound_violation_handler (struct gdbarch *gdbarch, gdbarch_bound_violation_handler_ftype *bound_violation_handler);
+
 /* GDB's standard (or well known) register numbers.  These can map onto
    a real register or a pseudo (computed) register or not be defined at
    all (-1).
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index f80cd51..edd155a 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -446,6 +446,11 @@ M:int:ax_pseudo_register_collect:struct agent_expr *ax, int reg:ax, reg
 # Return -1 if something goes wrong, 0 otherwise.
 M:int:ax_pseudo_register_push_stack:struct agent_expr *ax, int reg:ax, reg
 
+# Function called when a segmentation fault signal is received by the inferior,
+# having SIGCODE 3 (SIG_CODE_BOUNDARY_FAULT).
+# UIOUT is the output stream where the handler will place information.
+M:void:bound_violation_handler:struct ui_out *uiout:uiout
+
 # GDB's standard (or well known) register numbers.  These can map onto
 # a real register or a pseudo (computed) register or not be defined at
 # all (-1).
@@ -1247,6 +1252,7 @@ struct ravenscar_arch_ops;
 struct elf_internal_linux_prpsinfo;
 struct mem_range;
 struct syscalls_info;
+struct ui_out;
 
 #include "regcache.h"
 
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index af39e78..96c8e06 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -30,6 +30,7 @@
 #include "i386-tdep.h"
 #include "i386-linux-tdep.h"
 #include "linux-tdep.h"
+#include "utils.h"
 #include "glibc-tdep.h"
 #include "solib-svr4.h"
 #include "symtab.h"
@@ -384,6 +385,48 @@ i386_canonicalize_syscall (int syscall)
     return gdb_sys_no_syscall;
 }
 
+void
+i386_mpx_bound_violation_handler (struct gdbarch *gdbarch, struct ui_out *uiout)
+{
+  CORE_ADDR lower_bound, upper_bound, access;
+  int is_upper;
+
+  if (!i386_mpx_enabled ())
+    return;
+  TRY
+    {
+      lower_bound
+        = parse_and_eval_long ("$_siginfo._sifields._sigfault._addr_bnd._lower");
+      upper_bound
+        = parse_and_eval_long ("$_siginfo._sifields._sigfault._addr_bnd._upper");
+      access
+        = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
+    }
+  CATCH (exception, RETURN_MASK_ALL)
+    {
+    return;
+    }
+  END_CATCH
+
+  is_upper = (access > upper_bound ? 1 : 0);
+
+  ui_out_text (uiout, "\n");
+  if (is_upper)
+    ui_out_field_string (uiout, "sigcode-meaning", "upper bound violation");
+  else
+    ui_out_field_string (uiout, "sigcode-meaning", "lower bound violation");
+
+  ui_out_text (uiout, " - bounds {lbound = ");
+  ui_out_field_fmt (uiout,"lower-bound", "%s", paddress (gdbarch, lower_bound));
+  ui_out_text (uiout, ", ubound = ");
+  ui_out_field_fmt (uiout,"upper-bound", "%s", paddress (gdbarch, upper_bound));
+  ui_out_text (uiout, "}");
+  ui_out_text (uiout, " accessing ");
+  ui_out_field_fmt (uiout,"bound-access", "%s", paddress (gdbarch, access));
+
+  return;
+}
+
 /* Parse the arguments of current system call instruction and record
    the values of the registers and memory that will be changed into
    "record_arch_list".  This instruction is "int 0x80" (Linux
@@ -1002,6 +1045,8 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
                                   i386_linux_get_syscall_number);
 
   set_gdbarch_get_siginfo_type (gdbarch, x86_linux_get_siginfo_type);
+  set_gdbarch_bound_violation_handler(gdbarch,
+                                      i386_mpx_bound_violation_handler);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h
index f8e0074..5dc22ca 100644
--- a/gdb/i386-linux-tdep.h
+++ b/gdb/i386-linux-tdep.h
@@ -37,6 +37,11 @@
 /* Get XSAVE extended state xcr0 from core dump.  */
 extern uint64_t i386_linux_core_read_xcr0 (bfd *abfd);
 
+/* Handles and displays information related to the MPX bound violation
+   to the user.  */
+void
+i386_mpx_bound_violation_handler (struct gdbarch *gdbarch, struct ui_out *uiout);
+
 /* Linux target description.  */
 extern struct target_desc *tdesc_i386_linux;
 extern struct target_desc *tdesc_i386_mmx_linux;
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index b706463..b5d0d14 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -8651,9 +8651,7 @@ i386_mpx_bd_base (void)
   return ret & MPX_BASE_MASK;
 }
 
-/* Check if the current target is MPX enabled.  */
-
-static int
+int
 i386_mpx_enabled (void)
 {
   const struct gdbarch_tdep *tdep = gdbarch_tdep (get_current_arch ());
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 10d2772..26933f2 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -420,6 +420,8 @@ extern int i386_process_record (struct gdbarch *gdbarch,
                                 struct regcache *regcache, CORE_ADDR addr);
 extern const struct target_desc *i386_target_description (uint64_t xcr0);
 
+/* Verify if target is MPX enabled.  */
+extern int i386_mpx_enabled (void);
 \f
 
 /* Functions and variables exported from i386bsd-tdep.c.  */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 64c729e..87b930e 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -7893,6 +7893,36 @@ print_exited_reason (struct ui_out *uiout, int exitstatus)
     }
 }
 
+/*  Value of the sigcode in case of a boundary fault.  */
+
+#define SIG_CODE_BONDARY_FAULT 3
+
+/* Verifies if a received segmentation fault is a boundary fault.
+   In the case it is it calls the architecture dependent function
+   to handle the boundary fault.  */
+
+static void
+handle_segmentation_faults (struct ui_out *uiout)
+{
+  long sig_code = 0;
+  struct regcache *regcache = get_current_regcache ();
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+
+  TRY
+    {
+      sig_code = parse_and_eval_long ("$_siginfo.si_code\n");
+    }
+  CATCH (exception, RETURN_MASK_ALL)
+    {
+      return;
+    }
+  END_CATCH
+
+  if (sig_code == SIG_CODE_BONDARY_FAULT
+      && gdbarch_bound_violation_handler_p (gdbarch))
+    gdbarch_bound_violation_handler (gdbarch, uiout);
+}
+
 void
 print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
 {
@@ -7922,6 +7952,10 @@ print_signal_received_reason (struct ui_out *uiout, enum gdb_signal siggnal)
       annotate_signal_string ();
       ui_out_field_string (uiout, "signal-meaning",
 			   gdb_signal_to_string (siggnal));
+
+      if (siggnal == GDB_SIGNAL_SEGV)
+	handle_segmentation_faults (uiout);
+
       annotate_signal_string_end ();
     }
   ui_out_text (uiout, ".\n");
diff --git a/gdb/testsuite/gdb.arch/i386-mpx-sigsegv.c b/gdb/testsuite/gdb.arch/i386-mpx-sigsegv.c
new file mode 100644
index 0000000..7500352
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-mpx-sigsegv.c
@@ -0,0 +1,120 @@
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <walfred.tedeschi@intel.com>
+
+   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/>.  */
+
+#include "x86-cpuid.h"
+#include <stdio.h>
+
+#define OUR_SIZE    5
+
+int gx[OUR_SIZE];
+int ga[OUR_SIZE];
+int gb[OUR_SIZE];
+int gc[OUR_SIZE];
+int gd[OUR_SIZE];
+
+unsigned int
+have_mpx (void)
+{
+  unsigned int eax, ebx, ecx, edx;
+
+  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+    return 0;
+
+  if ((ecx & bit_OSXSAVE) == bit_OSXSAVE)
+    {
+      if (__get_cpuid_max (0, NULL) < 7)
+	return 0;
+
+      __cpuid_count (7, 0, eax, ebx, ecx, edx);
+
+      if ((ebx & bit_MPX) == bit_MPX)
+	return 1;
+      else
+	return 0;
+    }
+  return 0;
+}
+
+int
+bp1 (int value)
+{
+  return 1;
+}
+
+int
+bp2 (int value)
+{
+  return 1;
+}
+
+void
+upper (int * p, int * a, int * b, int * c, int * d, int len)
+{
+  int value;
+  value = *(p + len);
+  value = *(a + len);
+  value = *(b + len);
+  value = *(c + len);
+  value = *(d + len);
+}
+
+void
+lower (int * p, int * a, int * b, int * c, int * d, int len)
+{
+  int value;
+  value = *(p - len);
+  value = *(a - len);
+  value = *(b - len);
+  value = *(c - len);
+  bp2 (value);
+  value = *(d - len);
+}
+
+int
+main (void)
+{
+  if (have_mpx ())
+    {
+      int sx[OUR_SIZE];
+      int sa[OUR_SIZE];
+      int sb[OUR_SIZE];
+      int sc[OUR_SIZE];
+      int sd[OUR_SIZE];
+      int *x, *a, *b, *c, *d;
+
+      x = calloc (OUR_SIZE, sizeof (int));
+      a = calloc (OUR_SIZE, sizeof (int));
+      b = calloc (OUR_SIZE, sizeof (int));
+      c = calloc (OUR_SIZE, sizeof (int));
+      d = calloc (OUR_SIZE, sizeof (int));
+
+      upper (x, a, b, c, d, OUR_SIZE + 2);
+      upper (sx, sa, sb, sc, sd, OUR_SIZE + 2);
+      upper (gx, ga, gb, gc, gd, OUR_SIZE + 2);
+      lower (x, a, b, c, d, 1);
+      lower (sx, sa, sb, sc, sd, 1);
+      bp1 (*x);
+      lower (gx, ga, gb, gc, gd, 1);
+
+      free (x);
+      free (a);
+      free (b);
+      free (c);
+      free (d);
+    }
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/i386-mpx-sigsegv.exp b/gdb/testsuite/gdb.arch/i386-mpx-sigsegv.exp
new file mode 100644
index 0000000..2de6b4a
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-mpx-sigsegv.exp
@@ -0,0 +1,86 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp. <walfred.tedeschi@intel.com>
+#
+# 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/>.
+
+
+if { ![istarget i?86-*-*] && ![istarget x86_64-*-* ] } {
+    verbose "Skipping x86 MPX tests."
+    return
+}
+
+standard_testfile
+
+set comp_flags "-mmpx -fcheck-pointer-bounds -I${srcdir}/../nat/"
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
+ [list debug nowarnings additional_flags=${comp_flags}]] } {
+    return -1
+}
+
+if ![runto_main] {
+    untested "could not run to main"
+    return -1
+}
+
+gdb_test_multiple "print have_mpx ()" "have mpx" {
+    -re ".. = 1\r\n$gdb_prompt " {
+        pass "check whether processor supports MPX"
+        }
+    -re ".. = 0\r\n$gdb_prompt " {
+        verbose "processor does not support MPX; skipping MPX tests"
+        return
+        }
+}
+
+set segv_lower_bound ".*Program received signal SIGSEGV,\
+        Segmentation fault\r\nlower bound violation - bounds \\\{lbound\
+        = 0x\[0-9a-fA-F\]+, ubound = 0x\[0-9a-fA-F\]+\\\} accessing\
+        0x\[0-9a-fA-F\]+.*$gdb_prompt $"
+
+set segv_upper_bound ".*Program received signal SIGSEGV,\
+        Segmentation fault\r\nupper bound violation - bounds \\\{lbound\
+        = 0x\[0-9a-fA-F\]+, ubound = 0x\[0-9a-fA-F\]+\\\} accessing\
+        0x\[0-9a-fA-F\]+.*$gdb_prompt $"
+
+for {set i 0} {$i < 15} {incr i} {
+    set message "MPX signal segv Upper: ${i}"
+    gdb_test_multiple "continue" "$message ${i}" {
+        -re $segv_upper_bound {
+            pass "$message"
+            }
+        -re ".*$inferior_exited_re normally.*$gdb_prompt $" {
+            fail "$message"
+            break
+            }
+    }
+    gdb_test "where" ".*#0  0x\[0-9a-fA-F\]+ in upper.*"\
+             "$message: should be in upper"
+}
+
+for {set i 0} {$i < 15} {incr i} {
+    set message "MPX signal segv Lower: ${i}"
+    gdb_test_multiple "continue" "$message ${i}" {
+         -re $segv_lower_bound {
+             pass "$message ${i}"
+             }
+         -re ".*$inferior_exited_re normally.*$gdb_prompt $" {
+             fail "$message ${i}"
+             break
+             }
+    }
+    gdb_test "where" ".*#0  0x\[0-9a-fA-F\]+ in lower.*"\
+             "$message: should be in lower"
+}
diff --git a/gdb/testsuite/gdb.arch/i386-mpx-simple_segv.c b/gdb/testsuite/gdb.arch/i386-mpx-simple_segv.c
new file mode 100644
index 0000000..5317369
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-mpx-simple_segv.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 2015 Free Software Foundation, Inc.
+
+   Contributed by Intel Corp. <walfred.tedeschi@intel.com>
+
+   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/>.  */
+
+#include "x86-cpuid.h"
+#include <stdio.h>
+
+#define OUR_SIZE    5
+
+unsigned int
+have_mpx (void)
+{
+  unsigned int eax, ebx, ecx, edx;
+
+  if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+    return 0;
+
+  if ((ecx & bit_OSXSAVE) == bit_OSXSAVE)
+    {
+      if (__get_cpuid_max (0, NULL) < 7)
+	return 0;
+
+      __cpuid_count (7, 0, eax, ebx, ecx, edx);
+
+      if ((ebx & bit_MPX) == bit_MPX)
+	return 1;
+      else
+	return 0;
+    }
+  return 0;
+}
+
+void
+upper (int * p, int len)
+{
+  int value;
+  len++;			/* b0-size-test.  */
+  value = *(p + len);
+}
+
+int
+main (void)
+{
+  if (have_mpx ())
+    {
+      int a = 0;			/* Dummy variable for debugging purposes.  */
+      int sx[OUR_SIZE];
+      a++;				/* register-eval.  */
+      upper (sx, OUR_SIZE + 2);
+      return sx[1];
+    }
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/i386-mpx-simple_segv.exp b/gdb/testsuite/gdb.arch/i386-mpx-simple_segv.exp
new file mode 100644
index 0000000..6b099d6
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-mpx-simple_segv.exp
@@ -0,0 +1,129 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+#
+# Contributed by Intel Corp.  <walfred.tedeschi@intel.com>
+#
+# 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/>.
+
+# Testing handle setup together with boundary violation signals.
+#
+# Some states are not allowed as reported on the manual, as noprint
+# implies nostop, but nostop might print.
+#
+# Caveat: Setting the handle to nopass, ends up in a endless loop.
+
+if { ![istarget i?86-*-*] && ![istarget x86_64-*-* ] } {
+    verbose "Skipping x86 MPX tests."
+    return
+}
+
+standard_testfile
+
+set comp_flags "-mmpx -fcheck-pointer-bounds -I${srcdir}/../nat/"
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
+ [list debug nowarnings additional_flags=${comp_flags}]] } {
+    return -1
+}
+
+if ![runto_main] {
+    untested "could not run to main"
+    return -1
+}
+
+send_gdb "print have_mpx ()\r"
+gdb_expect {
+    -re ".. = 1\r\n$gdb_prompt " {
+        pass "check whether processor supports MPX"
+        }
+    -re ".. = 0\r\n$gdb_prompt " {
+        verbose "processor does not support MPX; skipping MPX tests"
+        return
+        }
+}
+
+set segv_bound_with_prompt ".*Program received signal SIGSEGV,\
+        Segmentation fault\r\nupper bound violation - bounds \\\{lbound\
+        = 0x\[0-9a-fA-F\]+, ubound = 0x\[0-9a-fA-F\]+\\\} accessing\
+        0x\[0-9a-fA-F\]+.*$gdb_prompt $"
+
+set segv_bound_with_exit ".*Program received signal SIGSEGV,\
+        Segmentation fault\r\nupper bound violation - bounds \\\{lbound\
+        = 0x\[0-9a-fA-F\]+, ubound = 0x\[0-9a-fA-F\]+\\\} accessing\
+        0x\[0-9a-fA-F\]+.*$inferior_exited_re.*"
+
+set segv_with_exit ".*Program received signal SIGSEGV,\
+        Segmentation fault.*$inferior_exited_re.*"
+
+# Using the handler for SIGSEGV as "print pass stop"
+set parameters "print pass stop"
+runto_main
+send_gdb "handle SIGSEGV $parameters\n"
+send_gdb "continue\n"
+
+gdb_expect {
+     -re $segv_bound_with_prompt {
+         pass $parameters
+         }
+}
+gdb_test "where" ".*#0  0x\[0-9a-fA-F\]+ in upper.*"\
+         "should be in upper; $parameters"
+
+# Using the handler for SIGSEGV as "print pass nostop"
+set parameters "print pass nostop"
+runto_main
+
+gdb_test "handle SIGSEGV $parameters" "" "Setting\
+the handler for segfault 0"
+
+gdb_test_multiple "continue" "test 0" {
+    -re $segv_with_exit {
+        pass $parameters
+        }
+    -re "$gdb_prompt $" {
+        fail $parameters
+        }
+}
+
+gdb_test "where" "No stack." "no inferior $parameters"
+
+# Using the handler for SIGSEGV as "print nopass stop"
+set parameters "print nopass stop"
+
+runto_main
+gdb_test "handle SIGSEGV $parameters" "" "Setting\
+the handler for segfault 1"
+
+gdb_test_multiple "continue" "test 1" {
+     -re $segv_bound_with_prompt {
+         pass $parameters
+         }
+}
+
+gdb_test "where" ".*#0  0x\[0-9a-fA-F\]+ in upper.*"\
+         "should be in upper $parameters"
+
+# print nopass stop
+set parameters "noprint pass nostop"
+runto_main
+
+gdb_test "handle SIGSEGV $parameters" "" "Setting\
+the handler for segfault 2"
+
+gdb_test_multiple "continue" "test 2" {
+    -re "Continuing\..*$inferior_exited_re.*" {
+        pass $parameters
+        }
+}
+
+gdb_test "where" "No stack." "no inferior $parameters"
-- 
2.1.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH V4 1/6] Merge gdb and gdbserver implementations for siginfo
  2016-01-21 14:48 [PATCH V4 0/6] Intel MPX bound violation support Walfred Tedeschi
  2016-01-21 14:48 ` [PATCH V4 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
  2016-01-21 14:49 ` [PATCH V4 5/6] Adaptation of siginfo fixup for the new bnd fields Walfred Tedeschi
@ 2016-01-21 14:49 ` Walfred Tedeschi
  2016-01-21 15:05   ` Pedro Alves
  2016-01-21 14:49 ` [PATCH V4 4/6] Add bound related fields to the siginfo structure Walfred Tedeschi
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-21 14:49 UTC (permalink / raw)
  To: palves, eliz, brobecker; +Cc: gdb-patches, Walfred Tedeschi

Extract the compatible siginfo handling from amd64-linux-nat.c and
gdbserver/linux-x86-low to a new file nat/amd64-linux-siginfo.c.


2016-01-15  Walfred Tedeschi  <walfred.tedeschi@intel.com>

gdb/ChangeLog:

	* nat/amd64-linux-siginfo.c: New file.
	* nat/amd64-linux-siginfo.h: New file.
	* Makefile.in (HFILES_NO_SRCDIR): Add nat/amd64-linux-siginfo.h.
	(amd64-linux-siginfo.o): New rule.
	* config/i386/linux64.mh (NATDEPFILES): Add amd64-linux-siginfo.o.
	* amd64-linux-nat.c (nat/amd64-linux-siginfo.h): New include.
	(compat_siginfo_from_siginfo, siginfo_from_compat_siginfo)
	(compat_x32_siginfo_from_siginfo, siginfo_from_compat_x32_siginfo)
	(compat_timeval, compat_sigval, compat_x32_clock, cpt_si_pid)
	(cpt_si_uid, cpt_si_timerid, cpt_si_overrun, cpt_si_status)
	(cpt_si_utime, cpt_si_stime, cpt_si_ptr, cpt_si_addr, cpt_si_band)
	(cpt_si_fd, si_timerid, si_overrun): Move to nat/amd64-linux-siginfo.c.


gdb/gdbserver/ChangeLog:

	* configure.srv (x86_64-*-linux*): Add amd64-linux-siginfo.o
	to srv_tgtobj.
	(i[34567]86-*-linux*): Add amd64-linux-siginfo.o
	to srv_tgtobj.
	* linux-x86-low.c [__x86_64__]: Include
	"nat/amd64-linux-siginfo.h".
	(compat_siginfo_from_siginfo, siginfo_from_compat_siginfo)
	(compat_x32_siginfo_from_siginfo, siginfo_from_compat_x32_siginfo)
	(compat_timeval, compat_sigval, compat_x32_clock, cpt_si_pid)
	(cpt_si_uid, cpt_si_timerid, cpt_si_overrun, cpt_si_status)
	(cpt_si_utime, cpt_si_stime, cpt_si_ptr, cpt_si_addr, cpt_si_band)
	(cpt_si_fd, si_timerid, si_overrun): Move from
	nat/amd64-linux-siginfo.c.
	* Makefile.in (amd64-linux-siginfo.o:): New rule.

---
 gdb/Makefile.in               |   6 +-
 gdb/amd64-linux-nat.c         | 431 +--------------------------------------
 gdb/config/i386/linux64.mh    |   2 +-
 gdb/gdbserver/Makefile.in     |   3 +
 gdb/gdbserver/configure.srv   |   4 +-
 gdb/gdbserver/linux-x86-low.c | 423 +-------------------------------------
 gdb/nat/amd64-linux-siginfo.c | 462 ++++++++++++++++++++++++++++++++++++++++++
 gdb/nat/amd64-linux-siginfo.h |  44 ++++
 8 files changed, 531 insertions(+), 844 deletions(-)
 create mode 100644 gdb/nat/amd64-linux-siginfo.c
 create mode 100644 gdb/nat/amd64-linux-siginfo.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 895ece6..869fe9f 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -986,7 +986,7 @@ i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \
 common/common-debug.h common/cleanups.h common/gdb_setjmp.h \
 common/common-exceptions.h target/target.h common/symbol.h \
 common/common-regcache.h fbsd-tdep.h nat/linux-personality.h \
-common/fileio.h nat/x86-linux.h nat/x86-linux-dregs.h \
+common/fileio.h nat/x86-linux.h nat/x86-linux-dregs.h nat/amd64-linux-siginfo.h\
 nat/linux-namespaces.h arch/arm.h common/gdb_sys_time.h arch/aarch64-insn.h \
 tid-parse.h
 
@@ -2352,6 +2352,10 @@ x86-linux-dregs.o: ${srcdir}/nat/x86-linux-dregs.c
 	$(COMPILE) $(srcdir)/nat/x86-linux-dregs.c
 	$(POSTCOMPILE)
 
+amd64-linux-siginfo.o: ${srcdir}/nat/amd64-linux-siginfo.c
+	$(COMPILE) $(srcdir)/nat/amd64-linux-siginfo.c
+	$(POSTCOMPILE)
+
 linux-namespaces.o: ${srcdir}/nat/linux-namespaces.c
 	$(COMPILE) $(srcdir)/nat/linux-namespaces.c
 	$(POSTCOMPILE)
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 32cbd46..391a646 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -38,6 +38,7 @@
 
 #include "x86-linux-nat.h"
 #include "nat/linux-ptrace.h"
+#include "nat/amd64-linux-siginfo.h"
 
 /* Mapping between the general-purpose registers in GNU/Linux x86-64
    `struct user' format and GDB's register cache layout for GNU/Linux
@@ -320,409 +321,6 @@ ps_get_thread_area (const struct ps_prochandle *ph,
 }
 \f
 
-/* When GDB is built as a 64-bit application on linux, the
-   PTRACE_GETSIGINFO data is always presented in 64-bit layout.  Since
-   debugging a 32-bit inferior with a 64-bit GDB should look the same
-   as debugging it with a 32-bit GDB, we do the 32-bit <-> 64-bit
-   conversion in-place ourselves.  */
-
-/* These types below (compat_*) define a siginfo type that is layout
-   compatible with the siginfo type exported by the 32-bit userspace
-   support.  */
-
-typedef int compat_int_t;
-typedef unsigned int compat_uptr_t;
-
-typedef int compat_time_t;
-typedef int compat_timer_t;
-typedef int compat_clock_t;
-
-struct compat_timeval
-{
-  compat_time_t tv_sec;
-  int tv_usec;
-};
-
-typedef union compat_sigval
-{
-  compat_int_t sival_int;
-  compat_uptr_t sival_ptr;
-} compat_sigval_t;
-
-typedef struct compat_siginfo
-{
-  int si_signo;
-  int si_errno;
-  int si_code;
-
-  union
-  {
-    int _pad[((128 / sizeof (int)) - 3)];
-
-    /* kill() */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-    } _kill;
-
-    /* POSIX.1b timers */
-    struct
-    {
-      compat_timer_t _tid;
-      int _overrun;
-      compat_sigval_t _sigval;
-    } _timer;
-
-    /* POSIX.1b signals */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-      compat_sigval_t _sigval;
-    } _rt;
-
-    /* SIGCHLD */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-      int _status;
-      compat_clock_t _utime;
-      compat_clock_t _stime;
-    } _sigchld;
-
-    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-    struct
-    {
-      unsigned int _addr;
-    } _sigfault;
-
-    /* SIGPOLL */
-    struct
-    {
-      int _band;
-      int _fd;
-    } _sigpoll;
-  } _sifields;
-} compat_siginfo_t;
-
-/* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes.  */
-typedef struct compat_x32_clock
-{
-  int lower;
-  int upper;
-} compat_x32_clock_t;
-
-typedef struct compat_x32_siginfo
-{
-  int si_signo;
-  int si_errno;
-  int si_code;
-
-  union
-  {
-    int _pad[((128 / sizeof (int)) - 3)];
-
-    /* kill() */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-    } _kill;
-
-    /* POSIX.1b timers */
-    struct
-    {
-      compat_timer_t _tid;
-      int _overrun;
-      compat_sigval_t _sigval;
-    } _timer;
-
-    /* POSIX.1b signals */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-      compat_sigval_t _sigval;
-    } _rt;
-
-    /* SIGCHLD */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-      int _status;
-      compat_x32_clock_t _utime;
-      compat_x32_clock_t _stime;
-    } _sigchld;
-
-    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-    struct
-    {
-      unsigned int _addr;
-    } _sigfault;
-
-    /* SIGPOLL */
-    struct
-    {
-      int _band;
-      int _fd;
-    } _sigpoll;
-  } _sifields;
-} compat_x32_siginfo_t;
-
-#define cpt_si_pid _sifields._kill._pid
-#define cpt_si_uid _sifields._kill._uid
-#define cpt_si_timerid _sifields._timer._tid
-#define cpt_si_overrun _sifields._timer._overrun
-#define cpt_si_status _sifields._sigchld._status
-#define cpt_si_utime _sifields._sigchld._utime
-#define cpt_si_stime _sifields._sigchld._stime
-#define cpt_si_ptr _sifields._rt._sigval.sival_ptr
-#define cpt_si_addr _sifields._sigfault._addr
-#define cpt_si_band _sifields._sigpoll._band
-#define cpt_si_fd _sifields._sigpoll._fd
-
-/* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
-   In their place is si_timer1,si_timer2.  */
-#ifndef si_timerid
-#define si_timerid si_timer1
-#endif
-#ifndef si_overrun
-#define si_overrun si_timer2
-#endif
-
-static void
-compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
-{
-  memset (to, 0, sizeof (*to));
-
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
-
-  if (to->si_code == SI_TIMER)
-    {
-      to->cpt_si_timerid = from->si_timerid;
-      to->cpt_si_overrun = from->si_overrun;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
-    }
-  else if (to->si_code == SI_USER)
-    {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-    }
-  else if (to->si_code < 0)
-    {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
-    }
-  else
-    {
-      switch (to->si_signo)
-	{
-	case SIGCHLD:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_status = from->si_status;
-	  to->cpt_si_utime = from->si_utime;
-	  to->cpt_si_stime = from->si_stime;
-	  break;
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	  to->cpt_si_addr = (intptr_t) from->si_addr;
-	  break;
-	case SIGPOLL:
-	  to->cpt_si_band = from->si_band;
-	  to->cpt_si_fd = from->si_fd;
-	  break;
-	default:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
-	  break;
-	}
-    }
-}
-
-static void
-siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
-{
-  memset (to, 0, sizeof (*to));
-
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
-
-  if (to->si_code == SI_TIMER)
-    {
-      to->si_timerid = from->cpt_si_timerid;
-      to->si_overrun = from->cpt_si_overrun;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
-    }
-  else if (to->si_code == SI_USER)
-    {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-    }
-  if (to->si_code < 0)
-    {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
-    }
-  else
-    {
-      switch (to->si_signo)
-	{
-	case SIGCHLD:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_status = from->cpt_si_status;
-	  to->si_utime = from->cpt_si_utime;
-	  to->si_stime = from->cpt_si_stime;
-	  break;
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
-	  break;
-	case SIGPOLL:
-	  to->si_band = from->cpt_si_band;
-	  to->si_fd = from->cpt_si_fd;
-	  break;
-	default:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
-	  break;
-	}
-    }
-}
-
-static void
-compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
-				 siginfo_t *from)
-{
-  memset (to, 0, sizeof (*to));
-
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
-
-  if (to->si_code == SI_TIMER)
-    {
-      to->cpt_si_timerid = from->si_timerid;
-      to->cpt_si_overrun = from->si_overrun;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
-    }
-  else if (to->si_code == SI_USER)
-    {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-    }
-  else if (to->si_code < 0)
-    {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
-    }
-  else
-    {
-      switch (to->si_signo)
-	{
-	case SIGCHLD:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_status = from->si_status;
-	  memcpy (&to->cpt_si_utime, &from->si_utime,
-		  sizeof (to->cpt_si_utime));
-	  memcpy (&to->cpt_si_stime, &from->si_stime,
-		  sizeof (to->cpt_si_stime));
-	  break;
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	  to->cpt_si_addr = (intptr_t) from->si_addr;
-	  break;
-	case SIGPOLL:
-	  to->cpt_si_band = from->si_band;
-	  to->cpt_si_fd = from->si_fd;
-	  break;
-	default:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
-	  break;
-	}
-    }
-}
-
-static void
-siginfo_from_compat_x32_siginfo (siginfo_t *to,
-				 compat_x32_siginfo_t *from)
-{
-  memset (to, 0, sizeof (*to));
-
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
-
-  if (to->si_code == SI_TIMER)
-    {
-      to->si_timerid = from->cpt_si_timerid;
-      to->si_overrun = from->cpt_si_overrun;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
-    }
-  else if (to->si_code == SI_USER)
-    {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-    }
-  if (to->si_code < 0)
-    {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
-    }
-  else
-    {
-      switch (to->si_signo)
-	{
-	case SIGCHLD:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_status = from->cpt_si_status;
-	  memcpy (&to->si_utime, &from->cpt_si_utime,
-		  sizeof (to->si_utime));
-	  memcpy (&to->si_stime, &from->cpt_si_stime,
-		  sizeof (to->si_stime));
-	  break;
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
-	  break;
-	case SIGPOLL:
-	  to->si_band = from->cpt_si_band;
-	  to->si_fd = from->cpt_si_fd;
-	  break;
-	default:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
-	  break;
-	}
-    }
-}
-
 /* Convert a native/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
@@ -737,34 +335,15 @@ amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
   /* Is the inferior 32-bit?  If so, then do fixup the siginfo
      object.  */
   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
-    {
-      gdb_assert (sizeof (siginfo_t) == sizeof (compat_siginfo_t));
-
-      if (direction == 0)
-	compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native);
-      else
-	siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf);
-
-      return 1;
-    }
+      return amd64_linux_siginfo_fixup_common (native, inf, direction,
+					       FIXUP_32);
   /* No fixup for native x32 GDB.  */
   else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
-    {
-      gdb_assert (sizeof (siginfo_t) == sizeof (compat_x32_siginfo_t));
-
-      if (direction == 0)
-	compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf,
-					 native);
-      else
-	siginfo_from_compat_x32_siginfo (native,
-					 (struct compat_x32_siginfo *) inf);
-
-      return 1;
-    }
+      return amd64_linux_siginfo_fixup_common (native, inf, direction,
+					       FIXUP_X32);
   else
     return 0;
 }
-\f
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 void _initialize_amd64_linux_nat (void);
diff --git a/gdb/config/i386/linux64.mh b/gdb/config/i386/linux64.mh
index 04cbb95..42d8df5 100644
--- a/gdb/config/i386/linux64.mh
+++ b/gdb/config/i386/linux64.mh
@@ -6,7 +6,7 @@ NATDEPFILES= inf-ptrace.o fork-child.o \
 	proc-service.o linux-thread-db.o linux-fork.o \
 	linux-procfs.o linux-ptrace.o linux-btrace.o \
 	linux-waitpid.o linux-personality.o x86-linux.o \
-	x86-linux-dregs.o linux-namespaces.o
+	x86-linux-dregs.o amd64-linux-siginfo.o linux-namespaces.o
 NAT_FILE= config/nm-linux.h
 NAT_CDEPS = $(srcdir)/proc-service.list
 
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 4719e48..8bccd5a 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -605,6 +605,9 @@ arm-get-next-pcs.o: ../arch/arm-get-next-pcs.c
 x86-dregs.o: ../nat/x86-dregs.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+amd64-linux-siginfo.o: ../nat/amd64-linux-siginfo.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
 linux-btrace.o: ../nat/linux-btrace.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 5f5112e..a54b9e7 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -118,8 +118,9 @@ case "${target}" in
 			if test "$gdb_cv_i386_is_x86_64" = yes ; then
 			    srv_regobj="$srv_regobj $srv_amd64_linux_regobj"
 			    srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
+			    srv_tgtobj="amd64-linux-siginfo.o"
 			fi
-			srv_tgtobj="$srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o"
+			srv_tgtobj="${srv_tgtobj} $srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o"
 			srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o"
 			srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
 			srv_linux_usrregs=yes
@@ -339,6 +340,7 @@ case "${target}" in
 			srv_tgtobj="$srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o"
 			srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o"
 			srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
+			srv_tgtobj="${srv_tgtobj} amd64-linux-siginfo.o"
 			srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
 			srv_linux_usrregs=yes # This is for i386 progs.
 			srv_linux_regsets=yes
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 4a01750..ff51a95 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -27,6 +27,10 @@
 #include "x86-xstate.h"
 #include "nat/gdb_ptrace.h"
 
+#ifdef __x86_64__
+#include "nat/amd64-linux-siginfo.h"
+#endif
+
 #include "gdb_proc_service.h"
 /* Don't include elf/common.h if linux/elf.h got included by
    gdb_proc_service.h.  */
@@ -670,399 +674,6 @@ 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.  */
 
-/* These types below (compat_*) define a siginfo type that is layout
-   compatible with the siginfo type exported by the 32-bit userspace
-   support.  */
-
-#ifdef __x86_64__
-
-typedef int compat_int_t;
-typedef unsigned int compat_uptr_t;
-
-typedef int compat_time_t;
-typedef int compat_timer_t;
-typedef int compat_clock_t;
-
-struct compat_timeval
-{
-  compat_time_t tv_sec;
-  int tv_usec;
-};
-
-typedef union compat_sigval
-{
-  compat_int_t sival_int;
-  compat_uptr_t sival_ptr;
-} compat_sigval_t;
-
-typedef struct compat_siginfo
-{
-  int si_signo;
-  int si_errno;
-  int si_code;
-
-  union
-  {
-    int _pad[((128 / sizeof (int)) - 3)];
-
-    /* kill() */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-    } _kill;
-
-    /* POSIX.1b timers */
-    struct
-    {
-      compat_timer_t _tid;
-      int _overrun;
-      compat_sigval_t _sigval;
-    } _timer;
-
-    /* POSIX.1b signals */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-      compat_sigval_t _sigval;
-    } _rt;
-
-    /* SIGCHLD */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-      int _status;
-      compat_clock_t _utime;
-      compat_clock_t _stime;
-    } _sigchld;
-
-    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-    struct
-    {
-      unsigned int _addr;
-    } _sigfault;
-
-    /* SIGPOLL */
-    struct
-    {
-      int _band;
-      int _fd;
-    } _sigpoll;
-  } _sifields;
-} compat_siginfo_t;
-
-/* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes.  */
-typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t;
-
-typedef struct compat_x32_siginfo
-{
-  int si_signo;
-  int si_errno;
-  int si_code;
-
-  union
-  {
-    int _pad[((128 / sizeof (int)) - 3)];
-
-    /* kill() */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-    } _kill;
-
-    /* POSIX.1b timers */
-    struct
-    {
-      compat_timer_t _tid;
-      int _overrun;
-      compat_sigval_t _sigval;
-    } _timer;
-
-    /* POSIX.1b signals */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-      compat_sigval_t _sigval;
-    } _rt;
-
-    /* SIGCHLD */
-    struct
-    {
-      unsigned int _pid;
-      unsigned int _uid;
-      int _status;
-      compat_x32_clock_t _utime;
-      compat_x32_clock_t _stime;
-    } _sigchld;
-
-    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-    struct
-    {
-      unsigned int _addr;
-    } _sigfault;
-
-    /* SIGPOLL */
-    struct
-    {
-      int _band;
-      int _fd;
-    } _sigpoll;
-  } _sifields;
-} compat_x32_siginfo_t __attribute__ ((__aligned__ (8)));
-
-#define cpt_si_pid _sifields._kill._pid
-#define cpt_si_uid _sifields._kill._uid
-#define cpt_si_timerid _sifields._timer._tid
-#define cpt_si_overrun _sifields._timer._overrun
-#define cpt_si_status _sifields._sigchld._status
-#define cpt_si_utime _sifields._sigchld._utime
-#define cpt_si_stime _sifields._sigchld._stime
-#define cpt_si_ptr _sifields._rt._sigval.sival_ptr
-#define cpt_si_addr _sifields._sigfault._addr
-#define cpt_si_band _sifields._sigpoll._band
-#define cpt_si_fd _sifields._sigpoll._fd
-
-/* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
-   In their place is si_timer1,si_timer2.  */
-#ifndef si_timerid
-#define si_timerid si_timer1
-#endif
-#ifndef si_overrun
-#define si_overrun si_timer2
-#endif
-
-static void
-compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
-{
-  memset (to, 0, sizeof (*to));
-
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
-
-  if (to->si_code == SI_TIMER)
-    {
-      to->cpt_si_timerid = from->si_timerid;
-      to->cpt_si_overrun = from->si_overrun;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
-    }
-  else if (to->si_code == SI_USER)
-    {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-    }
-  else if (to->si_code < 0)
-    {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
-    }
-  else
-    {
-      switch (to->si_signo)
-	{
-	case SIGCHLD:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_status = from->si_status;
-	  to->cpt_si_utime = from->si_utime;
-	  to->cpt_si_stime = from->si_stime;
-	  break;
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	  to->cpt_si_addr = (intptr_t) from->si_addr;
-	  break;
-	case SIGPOLL:
-	  to->cpt_si_band = from->si_band;
-	  to->cpt_si_fd = from->si_fd;
-	  break;
-	default:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
-	  break;
-	}
-    }
-}
-
-static void
-siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
-{
-  memset (to, 0, sizeof (*to));
-
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
-
-  if (to->si_code == SI_TIMER)
-    {
-      to->si_timerid = from->cpt_si_timerid;
-      to->si_overrun = from->cpt_si_overrun;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
-    }
-  else if (to->si_code == SI_USER)
-    {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-    }
-  else if (to->si_code < 0)
-    {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
-    }
-  else
-    {
-      switch (to->si_signo)
-	{
-	case SIGCHLD:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_status = from->cpt_si_status;
-	  to->si_utime = from->cpt_si_utime;
-	  to->si_stime = from->cpt_si_stime;
-	  break;
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
-	  break;
-	case SIGPOLL:
-	  to->si_band = from->cpt_si_band;
-	  to->si_fd = from->cpt_si_fd;
-	  break;
-	default:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
-	  break;
-	}
-    }
-}
-
-static void
-compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
-				 siginfo_t *from)
-{
-  memset (to, 0, sizeof (*to));
-
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
-
-  if (to->si_code == SI_TIMER)
-    {
-      to->cpt_si_timerid = from->si_timerid;
-      to->cpt_si_overrun = from->si_overrun;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
-    }
-  else if (to->si_code == SI_USER)
-    {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-    }
-  else if (to->si_code < 0)
-    {
-      to->cpt_si_pid = from->si_pid;
-      to->cpt_si_uid = from->si_uid;
-      to->cpt_si_ptr = (intptr_t) from->si_ptr;
-    }
-  else
-    {
-      switch (to->si_signo)
-	{
-	case SIGCHLD:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_status = from->si_status;
-	  to->cpt_si_utime = from->si_utime;
-	  to->cpt_si_stime = from->si_stime;
-	  break;
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	  to->cpt_si_addr = (intptr_t) from->si_addr;
-	  break;
-	case SIGPOLL:
-	  to->cpt_si_band = from->si_band;
-	  to->cpt_si_fd = from->si_fd;
-	  break;
-	default:
-	  to->cpt_si_pid = from->si_pid;
-	  to->cpt_si_uid = from->si_uid;
-	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
-	  break;
-	}
-    }
-}
-
-static void
-siginfo_from_compat_x32_siginfo (siginfo_t *to,
-				 compat_x32_siginfo_t *from)
-{
-  memset (to, 0, sizeof (*to));
-
-  to->si_signo = from->si_signo;
-  to->si_errno = from->si_errno;
-  to->si_code = from->si_code;
-
-  if (to->si_code == SI_TIMER)
-    {
-      to->si_timerid = from->cpt_si_timerid;
-      to->si_overrun = from->cpt_si_overrun;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
-    }
-  else if (to->si_code == SI_USER)
-    {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-    }
-  else if (to->si_code < 0)
-    {
-      to->si_pid = from->cpt_si_pid;
-      to->si_uid = from->cpt_si_uid;
-      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
-    }
-  else
-    {
-      switch (to->si_signo)
-	{
-	case SIGCHLD:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_status = from->cpt_si_status;
-	  to->si_utime = from->cpt_si_utime;
-	  to->si_stime = from->cpt_si_stime;
-	  break;
-	case SIGILL:
-	case SIGFPE:
-	case SIGSEGV:
-	case SIGBUS:
-	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
-	  break;
-	case SIGPOLL:
-	  to->si_band = from->cpt_si_band;
-	  to->si_fd = from->cpt_si_fd;
-	  break;
-	default:
-	  to->si_pid = from->cpt_si_pid;
-	  to->si_uid = from->cpt_si_uid;
-	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
-	  break;
-	}
-    }
-}
-
-#endif /* __x86_64__ */
-
 /* Convert a native/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
@@ -1079,30 +690,12 @@ x86_siginfo_fixup (siginfo_t *native, void *inf, int direction)
 
   /* Is the inferior 32-bit?  If so, then fixup the siginfo object.  */
   if (!is_64bit_tdesc ())
-    {
-      gdb_assert (sizeof (siginfo_t) == sizeof (compat_siginfo_t));
-
-      if (direction == 0)
-	compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native);
-      else
-	siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf);
-
-      return 1;
-    }
+      return amd64_linux_siginfo_fixup_common (native, inf, direction,
+					       FIXUP_32);
   /* No fixup for native x32 GDB.  */
   else if (!is_elf64 && sizeof (void *) == 8)
-    {
-      gdb_assert (sizeof (siginfo_t) == sizeof (compat_x32_siginfo_t));
-
-      if (direction == 0)
-	compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf,
-					 native);
-      else
-	siginfo_from_compat_x32_siginfo (native,
-					 (struct compat_x32_siginfo *) inf);
-
-      return 1;
-    }
+    return amd64_linux_siginfo_fixup_common (native, inf, direction,
+					     FIXUP_X32);
 #endif
 
   return 0;
diff --git a/gdb/nat/amd64-linux-siginfo.c b/gdb/nat/amd64-linux-siginfo.c
new file mode 100644
index 0000000..36b5505
--- /dev/null
+++ b/gdb/nat/amd64-linux-siginfo.c
@@ -0,0 +1,462 @@
+/* Low-level siginfo manipulation for amd64.
+
+   Copyright (C) 2002-2016 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include <signal.h>
+#include "common-defs.h"
+#include "amd64-linux-siginfo.h"
+
+/* These types below (compat_*) define a siginfo type that is layout
+   compatible with the siginfo type exported by the 32-bit userspace
+   support.  */
+
+typedef int compat_int_t;
+typedef unsigned int compat_uptr_t;
+
+typedef int compat_time_t;
+typedef int compat_timer_t;
+typedef int compat_clock_t;
+
+struct compat_timeval
+{
+  compat_time_t tv_sec;
+  int tv_usec;
+};
+
+typedef union compat_sigval
+{
+  compat_int_t sival_int;
+  compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+typedef struct compat_siginfo
+{
+  int si_signo;
+  int si_errno;
+  int si_code;
+
+  union
+  {
+    int _pad[((128 / sizeof (int)) - 3)];
+
+    /* kill() */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+    } _kill;
+
+    /* POSIX.1b timers */
+    struct
+    {
+      compat_timer_t _tid;
+      int _overrun;
+      compat_sigval_t _sigval;
+    } _timer;
+
+    /* POSIX.1b signals */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+      compat_sigval_t _sigval;
+    } _rt;
+
+    /* SIGCHLD */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+      int _status;
+      compat_clock_t _utime;
+      compat_clock_t _stime;
+    } _sigchld;
+
+    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+    struct
+    {
+      unsigned int _addr;
+    } _sigfault;
+
+    /* SIGPOLL */
+    struct
+    {
+      int _band;
+      int _fd;
+    } _sigpoll;
+  } _sifields;
+} compat_siginfo_t;
+
+/* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes.  */
+typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t;
+
+typedef struct compat_x32_siginfo
+{
+  int si_signo;
+  int si_errno;
+  int si_code;
+
+  union
+  {
+    int _pad[((128 / sizeof (int)) - 3)];
+
+    /* kill() */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+    } _kill;
+
+    /* POSIX.1b timers */
+    struct
+    {
+      compat_timer_t _tid;
+      int _overrun;
+      compat_sigval_t _sigval;
+    } _timer;
+
+    /* POSIX.1b signals */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+      compat_sigval_t _sigval;
+    } _rt;
+
+    /* SIGCHLD */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+      int _status;
+      compat_x32_clock_t _utime;
+      compat_x32_clock_t _stime;
+    } _sigchld;
+
+    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+    struct
+    {
+      unsigned int _addr;
+    } _sigfault;
+
+    /* SIGPOLL */
+    struct
+    {
+      int _band;
+      int _fd;
+    } _sigpoll;
+  } _sifields;
+} compat_x32_siginfo_t __attribute__ ((__aligned__ (8)));
+
+/* To simplify usage of siginfo fields.  */
+
+#define cpt_si_pid _sifields._kill._pid
+#define cpt_si_uid _sifields._kill._uid
+#define cpt_si_timerid _sifields._timer._tid
+#define cpt_si_overrun _sifields._timer._overrun
+#define cpt_si_status _sifields._sigchld._status
+#define cpt_si_utime _sifields._sigchld._utime
+#define cpt_si_stime _sifields._sigchld._stime
+#define cpt_si_ptr _sifields._rt._sigval.sival_ptr
+#define cpt_si_addr _sifields._sigfault._addr
+#define cpt_si_band _sifields._sigpoll._band
+#define cpt_si_fd _sifields._sigpoll._fd
+
+/* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
+   In their place is si_timer1,si_timer2.  */
+
+#ifndef si_timerid
+#define si_timerid si_timer1
+#endif
+#ifndef si_overrun
+#define si_overrun si_timer2
+#endif
+
+/*  Convert the system provided siginfo into compatible siginfo.  */
+
+static void
+compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
+{
+  memset (to, 0, sizeof (*to));
+
+  to->si_signo = from->si_signo;
+  to->si_errno = from->si_errno;
+  to->si_code = from->si_code;
+
+  if (to->si_code == SI_TIMER)
+    {
+      to->cpt_si_timerid = from->si_timerid;
+      to->cpt_si_overrun = from->si_overrun;
+      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+    }
+  else if (to->si_code == SI_USER)
+    {
+      to->cpt_si_pid = from->si_pid;
+      to->cpt_si_uid = from->si_uid;
+    }
+  else if (to->si_code < 0)
+    {
+      to->cpt_si_pid = from->si_pid;
+      to->cpt_si_uid = from->si_uid;
+      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+    }
+  else
+    {
+      switch (to->si_signo)
+	{
+	case SIGCHLD:
+	  to->cpt_si_pid = from->si_pid;
+	  to->cpt_si_uid = from->si_uid;
+	  to->cpt_si_status = from->si_status;
+	  to->cpt_si_utime = from->si_utime;
+	  to->cpt_si_stime = from->si_stime;
+	  break;
+	case SIGILL:
+	case SIGFPE:
+	case SIGSEGV:
+	case SIGBUS:
+	  to->cpt_si_addr = (intptr_t) from->si_addr;
+	  break;
+	case SIGPOLL:
+	  to->cpt_si_band = from->si_band;
+	  to->cpt_si_fd = from->si_fd;
+	  break;
+	default:
+	  to->cpt_si_pid = from->si_pid;
+	  to->cpt_si_uid = from->si_uid;
+	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
+	  break;
+	}
+    }
+}
+
+/* Convert the compatible siginfo into system siginfo.  */
+
+static void
+siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
+{
+  memset (to, 0, sizeof (*to));
+
+  to->si_signo = from->si_signo;
+  to->si_errno = from->si_errno;
+  to->si_code = from->si_code;
+
+  if (to->si_code == SI_TIMER)
+    {
+      to->si_timerid = from->cpt_si_timerid;
+      to->si_overrun = from->cpt_si_overrun;
+      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+    }
+  else if (to->si_code == SI_USER)
+    {
+      to->si_pid = from->cpt_si_pid;
+      to->si_uid = from->cpt_si_uid;
+    }
+  if (to->si_code < 0)
+    {
+      to->si_pid = from->cpt_si_pid;
+      to->si_uid = from->cpt_si_uid;
+      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+    }
+  else
+    {
+      switch (to->si_signo)
+	{
+	case SIGCHLD:
+	  to->si_pid = from->cpt_si_pid;
+	  to->si_uid = from->cpt_si_uid;
+	  to->si_status = from->cpt_si_status;
+	  to->si_utime = from->cpt_si_utime;
+	  to->si_stime = from->cpt_si_stime;
+	  break;
+	case SIGILL:
+	case SIGFPE:
+	case SIGSEGV:
+	case SIGBUS:
+	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
+	  break;
+	case SIGPOLL:
+	  to->si_band = from->cpt_si_band;
+	  to->si_fd = from->cpt_si_fd;
+	  break;
+	default:
+	  to->si_pid = from->cpt_si_pid;
+	  to->si_uid = from->cpt_si_uid;
+	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
+	  break;
+	}
+    }
+}
+
+/*  Convert the system provided siginfo into compatible x32 siginfo.  */
+
+static void
+compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
+				 siginfo_t *from)
+{
+  memset (to, 0, sizeof (*to));
+
+  to->si_signo = from->si_signo;
+  to->si_errno = from->si_errno;
+  to->si_code = from->si_code;
+
+  if (to->si_code == SI_TIMER)
+    {
+      to->cpt_si_timerid = from->si_timerid;
+      to->cpt_si_overrun = from->si_overrun;
+      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+    }
+  else if (to->si_code == SI_USER)
+    {
+      to->cpt_si_pid = from->si_pid;
+      to->cpt_si_uid = from->si_uid;
+    }
+  else if (to->si_code < 0)
+    {
+      to->cpt_si_pid = from->si_pid;
+      to->cpt_si_uid = from->si_uid;
+      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+    }
+  else
+    {
+      switch (to->si_signo)
+	{
+	case SIGCHLD:
+	  to->cpt_si_pid = from->si_pid;
+	  to->cpt_si_uid = from->si_uid;
+	  to->cpt_si_status = from->si_status;
+	  memcpy (&to->cpt_si_utime, &from->si_utime,
+		  sizeof (to->cpt_si_utime));
+	  memcpy (&to->cpt_si_stime, &from->si_stime,
+		  sizeof (to->cpt_si_stime));
+	  break;
+	case SIGILL:
+	case SIGFPE:
+	case SIGSEGV:
+	case SIGBUS:
+	  to->cpt_si_addr = (intptr_t) from->si_addr;
+	  break;
+	case SIGPOLL:
+	  to->cpt_si_band = from->si_band;
+	  to->cpt_si_fd = from->si_fd;
+	  break;
+	default:
+	  to->cpt_si_pid = from->si_pid;
+	  to->cpt_si_uid = from->si_uid;
+	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
+	  break;
+	}
+    }
+}
+
+/* Convert the compatible x32 siginfo into system siginfo.  */
+static void
+siginfo_from_compat_x32_siginfo (siginfo_t *to,
+				 compat_x32_siginfo_t *from)
+{
+  memset (to, 0, sizeof (*to));
+
+  to->si_signo = from->si_signo;
+  to->si_errno = from->si_errno;
+  to->si_code = from->si_code;
+
+  if (to->si_code == SI_TIMER)
+    {
+      to->si_timerid = from->cpt_si_timerid;
+      to->si_overrun = from->cpt_si_overrun;
+      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+    }
+  else if (to->si_code == SI_USER)
+    {
+      to->si_pid = from->cpt_si_pid;
+      to->si_uid = from->cpt_si_uid;
+    }
+  if (to->si_code < 0)
+    {
+      to->si_pid = from->cpt_si_pid;
+      to->si_uid = from->cpt_si_uid;
+      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+    }
+  else
+    {
+      switch (to->si_signo)
+	{
+	case SIGCHLD:
+	  to->si_pid = from->cpt_si_pid;
+	  to->si_uid = from->cpt_si_uid;
+	  to->si_status = from->cpt_si_status;
+	  memcpy (&to->si_utime, &from->cpt_si_utime,
+		  sizeof (to->si_utime));
+	  memcpy (&to->si_stime, &from->cpt_si_stime,
+		  sizeof (to->si_stime));
+	  break;
+	case SIGILL:
+	case SIGFPE:
+	case SIGSEGV:
+	case SIGBUS:
+	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
+	  break;
+	case SIGPOLL:
+	  to->si_band = from->cpt_si_band;
+	  to->si_fd = from->cpt_si_fd;
+	  break;
+	default:
+	  to->si_pid = from->cpt_si_pid;
+	  to->si_uid = from->cpt_si_uid;
+	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
+	  break;
+	}
+    }
+}
+
+/* Convert a native/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, then copy from NATIVE to INF.  */
+
+int
+amd64_linux_siginfo_fixup_common (siginfo_t *native, 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);
+      else
+	siginfo_from_compat_siginfo (native, (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);
+      else
+	siginfo_from_compat_x32_siginfo (native,
+					 (struct compat_x32_siginfo *) inf);
+
+      return 1;
+    }
+  return 0;
+}
diff --git a/gdb/nat/amd64-linux-siginfo.h b/gdb/nat/amd64-linux-siginfo.h
new file mode 100644
index 0000000..a396966
--- /dev/null
+++ b/gdb/nat/amd64-linux-siginfo.h
@@ -0,0 +1,44 @@
+/* Low-level siginfo manipulation for amd64.
+
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#ifndef AMD64_LINUX_SIGINFO_H
+#define AMD64_LINUX_SIGINFO_H 1
+
+
+/* When GDB is built as a 64-bit application on Linux, the
+   PTRACE_GETSIGINFO data is always presented in 64-bit layout.  Since
+   debugging a 32-bit inferior with a 64-bit GDB should look the same
+   as debugging it with a 32-bit GDB, we do the 32-bit <-> 64-bit
+   conversion in-place ourselves.  */
+
+/* Kind of siginfo fixup to be performed.  */
+
+enum amd64_siginfo_fixup_mode
+{
+  FIXUP_32 = 1,   /* Fixup for 32bit.  */
+  FIXUP_X32 = 2   /* Fixup for x32.  */
+};
+
+/* Common code for performing the fixup of the siginfo.  */
+
+int amd64_linux_siginfo_fixup_common (siginfo_t *native, gdb_byte *inf,
+				      int direction,
+				      enum amd64_siginfo_fixup_mode mode);
+
+#endif
-- 
2.1.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH V4 4/6] Add bound related fields to the siginfo structure.
  2016-01-21 14:48 [PATCH V4 0/6] Intel MPX bound violation support Walfred Tedeschi
                   ` (2 preceding siblings ...)
  2016-01-21 14:49 ` [PATCH V4 1/6] Merge gdb and gdbserver implementations for siginfo Walfred Tedeschi
@ 2016-01-21 14:49 ` Walfred Tedeschi
  2016-01-21 14:49 ` [PATCH V4 6/6] Intel MPX bound violation handling Walfred Tedeschi
  2016-01-21 14:49 ` [PATCH V4 2/6] Prepararion for new siginfo on Linux Walfred Tedeschi
  5 siblings, 0 replies; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-21 14:49 UTC (permalink / raw)
  To: palves, eliz, brobecker; +Cc: gdb-patches, Walfred Tedeschi

New kernel and glibc patches have introduced fields in the
segmentation fault fields.  New fields will be conditional and requested
on demand by the customers.

Kernel patch:
http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?id=ee1b58d36aa1b5a79eaba11f5c3633c88231da83

Glibc patch:
http://repo.or.cz/w/glibc.git/commit/d4358b51c26a634eb885955aea06cad26af6f696

2016-01-15  Walfred Tedeschi  <walfred.tedeschi@intel.com>

gdb/ChangeLog:

	* linux-tdep.c (linux_get_siginfo_type): Add the _addr_bnd
	structure to the siginfo conditionally if extra_fields is
	LINUX_SIGINFO_FIELD_ADDR_BND.

---
 gdb/linux-tdep.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index a49057f..0e72b5b 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -251,7 +251,7 @@ linux_get_siginfo_type_with_fields (struct gdbarch *gdbarch,
 				    linux_siginfo_extra_fields extra_fields)
 {
   struct linux_gdbarch_data *linux_gdbarch_data;
-  struct type *int_type, *uint_type, *long_type, *void_ptr_type;
+  struct type *int_type, *uint_type, *long_type, *void_ptr_type, *short_type;
   struct type *uid_type, *pid_type;
   struct type *sigval_type, *clock_type;
   struct type *siginfo_type, *sifields_type;
@@ -267,6 +267,8 @@ linux_get_siginfo_type_with_fields (struct gdbarch *gdbarch,
 				 1, "unsigned int");
   long_type = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch),
 				 0, "long");
+  short_type = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch),
+				 0, "short");
   void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void);
 
   /* sival_t */
@@ -344,6 +346,18 @@ linux_get_siginfo_type_with_fields (struct gdbarch *gdbarch,
   append_composite_type_field (type, "si_addr", void_ptr_type);
   append_composite_type_field (sifields_type, "_sigfault", type);
 
+  if (extra_fields == LINUX_SIGINFO_FIELD_ADDR_BND)
+    {
+      struct type *sigfault_bnd_fields;
+
+      append_composite_type_field (type, "_addr_lsb", short_type);
+      sigfault_bnd_fields = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
+      append_composite_type_field (sigfault_bnd_fields, "_lower", void_ptr_type);
+      append_composite_type_field (sigfault_bnd_fields, "_upper", void_ptr_type);
+      append_composite_type_field (type, "_addr_bnd", sigfault_bnd_fields);
+      append_composite_type_field (sifields_type, "_sigfault", type);
+    }
+
   /* _sigpoll */
   type = arch_composite_type (gdbarch, NULL, TYPE_CODE_STRUCT);
   append_composite_type_field (type, "si_band", long_type);
-- 
2.1.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH V4 2/6] Prepararion for new siginfo on Linux.
  2016-01-21 14:49 ` [PATCH V4 2/6] Prepararion for new siginfo on Linux Walfred Tedeschi
@ 2016-01-21 15:05   ` Pedro Alves
  0 siblings, 0 replies; 15+ messages in thread
From: Pedro Alves @ 2016-01-21 15:05 UTC (permalink / raw)
  To: Walfred Tedeschi, eliz, brobecker; +Cc: gdb-patches

This looks just like the same patch in v3, and my review
comments [1] were not addressed.  As this is recurring, I have to
call it out, sorry -- please make sure to review past review
comments carefully before resubmitting.  If you don't agree to some
review comment and decide to do things differently, reply to
the review saying so.  In any case, it's useful to reply anyway,
saying "I'll fix", or some such, so that there's a feedback loop.

[1] https://sourceware.org/ml/gdb-patches/2016-01/msg00490.html

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH V4 1/6] Merge gdb and gdbserver implementations for siginfo
  2016-01-21 14:49 ` [PATCH V4 1/6] Merge gdb and gdbserver implementations for siginfo Walfred Tedeschi
@ 2016-01-21 15:05   ` Pedro Alves
  0 siblings, 0 replies; 15+ messages in thread
From: Pedro Alves @ 2016-01-21 15:05 UTC (permalink / raw)
  To: Walfred Tedeschi, eliz, brobecker; +Cc: gdb-patches

On 01/21/2016 02:48 PM, Walfred Tedeschi wrote:
> Extract the compatible siginfo handling from amd64-linux-nat.c and
> gdbserver/linux-x86-low to a new file nat/amd64-linux-siginfo.c.
> 
> 
> 2016-01-15  Walfred Tedeschi  <walfred.tedeschi@intel.com>
> 
> gdb/ChangeLog:
> 
> 	* nat/amd64-linux-siginfo.c: New file.
> 	* nat/amd64-linux-siginfo.h: New file.
> 	* Makefile.in (HFILES_NO_SRCDIR): Add nat/amd64-linux-siginfo.h.
> 	(amd64-linux-siginfo.o): New rule.
> 	* config/i386/linux64.mh (NATDEPFILES): Add amd64-linux-siginfo.o.
> 	* amd64-linux-nat.c (nat/amd64-linux-siginfo.h): New include.
> 	(compat_siginfo_from_siginfo, siginfo_from_compat_siginfo)
> 	(compat_x32_siginfo_from_siginfo, siginfo_from_compat_x32_siginfo)
> 	(compat_timeval, compat_sigval, compat_x32_clock, cpt_si_pid)
> 	(cpt_si_uid, cpt_si_timerid, cpt_si_overrun, cpt_si_status)
> 	(cpt_si_utime, cpt_si_stime, cpt_si_ptr, cpt_si_addr, cpt_si_band)
> 	(cpt_si_fd, si_timerid, si_overrun): Move to nat/amd64-linux-siginfo.c.
> 
> 
> gdb/gdbserver/ChangeLog:
> 
> 	* configure.srv (x86_64-*-linux*): Add amd64-linux-siginfo.o
> 	to srv_tgtobj.
> 	(i[34567]86-*-linux*): Add amd64-linux-siginfo.o
> 	to srv_tgtobj.
> 	* linux-x86-low.c [__x86_64__]: Include
> 	"nat/amd64-linux-siginfo.h".
> 	(compat_siginfo_from_siginfo, siginfo_from_compat_siginfo)
> 	(compat_x32_siginfo_from_siginfo, siginfo_from_compat_x32_siginfo)
> 	(compat_timeval, compat_sigval, compat_x32_clock, cpt_si_pid)
> 	(cpt_si_uid, cpt_si_timerid, cpt_si_overrun, cpt_si_status)
> 	(cpt_si_utime, cpt_si_stime, cpt_si_ptr, cpt_si_addr, cpt_si_band)
> 	(cpt_si_fd, si_timerid, si_overrun): Move from
> 	nat/amd64-linux-siginfo.c.
> 	* Makefile.in (amd64-linux-siginfo.o:): New rule.

OK.  This patch stands on its own -- please go ahead an push it.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH V4 6/6] Intel MPX bound violation handling.
  2016-01-21 14:49 ` [PATCH V4 6/6] Intel MPX bound violation handling Walfred Tedeschi
@ 2016-01-21 16:23   ` Eli Zaretskii
       [not found]     ` <AC542571535E904D8E8ADAE745D60B194452CD61@IRSMSX104.ger.corp.intel.com>
  0 siblings, 1 reply; 15+ messages in thread
From: Eli Zaretskii @ 2016-01-21 16:23 UTC (permalink / raw)
  To: Walfred Tedeschi; +Cc: palves, brobecker, gdb-patches

> From: Walfred Tedeschi <walfred.tedeschi@intel.com>
> Cc: gdb-patches@sourceware.org, Walfred Tedeschi <walfred.tedeschi@intel.com>
> Date: Thu, 21 Jan 2016 15:48:25 +0100
> 
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -3,6 +3,21 @@
>  
>  *** Changes since GDB 7.10
>  
> +* Intel MPX boud violation handler.
> +
> +   A boundary violations is presented to the inferior as
> +   a segmentation fault having SIGCODE 3. In this case
                                           ^^
Two spaces between sentences, please.

> +   GDB  displays also the kind of violation (upper or lower), 
> +   bounds, poiter value and the memory accessed, besides displaying
              ^^^^^^
"pointer"

> +   the usual signal received and code location report.
> +
> +   As exemplified below:
> +   Program received signal SIGSEGV, Segmentation fault
> +   upper bound violation - bounds {lbound = 0x603010, ubound = 0x603023}
> +   accessing 0x60302f.
> +   0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
> +   c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68

May I suggest to say

  accessing address 0x60302f.

instead?  That would be more clear, I think.

> --- a/gdb/doc/gdb.texinfo
> +++ b/gdb/doc/gdb.texinfo
> @@ -22267,6 +22267,57 @@ whose bounds are to be changed, @var{lbound} and @var{ubound} are new values
>  for lower and upper bounds respectively.
>  @end table
>  
> +
> +A boundary violation is presented to the inferior as
> +a segmentation fault having SIGCODE 3. @value{GDBN} may display additional
                                        ^^
Two spaces.

> +information is displayed in this case.

"...may display additional information is displayed..."?  One of the
"display" and "displayed" is redundant here, I think.

> +                                          On @code{STOP} mode
> +@value{GDBN} will also display the kind of violation: "upper" or
> +"lower", bounds, pointer value and the address accessed.
> +On @code{NOSTOP} no additional information will be presented.

I suggest to say "In STOP mode" and "In NOSTOP mode".  "In", not "On".

> +The usual output of a segfault is:
> +@smallexample
> +Program received signal SIGSEGV, Segmentation fault
> +0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
> +c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
> +68        value = *(p + len);
> +@end smallexample
> +
> +In case it is a bound violation it will be presented as:
> +@smallexample
> +Program received signal SIGSEGV, Segmentation fault
> +upper bound violation - bounds @{lbound = 0x603010, ubound = 0x603023@}
> +accessing 0x60302f.
> +0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
> +c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
> +68        value = *(p + len);
> +@end smallexample

Why do we need to show here the output when no bound violation
happened?

Actually, why not move this description and the example to the
"Signals" node?  If I were a user who received such a notification,
the "Signals" node is where I would look for the explanations first.

Thanks.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: FW: [PATCH V4 6/6] Intel MPX bound violation handling.
       [not found]     ` <AC542571535E904D8E8ADAE745D60B194452CD61@IRSMSX104.ger.corp.intel.com>
@ 2016-01-21 17:34       ` Walfred Tedeschi
  2016-01-21 17:51         ` Eli Zaretskii
  0 siblings, 1 reply; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-21 17:34 UTC (permalink / raw)
  To: Eli Zaretskii, palves, brobecker, gdb-patches

> -----Original Message-----
> From: gdb-patches-owner@sourceware.org [mailto:gdb-patches-owner@sourceware.org] On Behalf Of Eli Zaretskii
> Sent: Thursday, January 21, 2016 5:23 PM
> To: Tedeschi, Walfred
> Cc: palves@redhat.com; brobecker@adacore.com; gdb-patches@sourceware.org
> Subject: Re: [PATCH V4 6/6] Intel MPX bound violation handling.
>
>> From: Walfred Tedeschi <walfred.tedeschi@intel.com>
>> Cc: gdb-patches@sourceware.org, Walfred Tedeschi
>> <walfred.tedeschi@intel.com>
>> Date: Thu, 21 Jan 2016 15:48:25 +0100
>>
>> --- a/gdb/NEWS
>> +++ b/gdb/NEWS
>> @@ -3,6 +3,21 @@
>>   
>>   *** Changes since GDB 7.10
>>   
>> +* Intel MPX boud violation handler.
>> +
>> +   A boundary violations is presented to the inferior as
>> +   a segmentation fault having SIGCODE 3. In this case
>                                             ^^ Two spaces between sentences, please.
ok!
>> +   GDB  displays also the kind of violation (upper or lower),
>> +   bounds, poiter value and the memory accessed, besides displaying
>                ^^^^^^
> "pointer"
>
>> +   the usual signal received and code location report.
>> +
>> +   As exemplified below:
>> +   Program received signal SIGSEGV, Segmentation fault
>> +   upper bound violation - bounds {lbound = 0x603010, ubound = 0x603023}
>> +   accessing 0x60302f.
>> +   0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
>> +   c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
> May I suggest to say
>
>    accessing address 0x60302f.
>
> instead?  That would be more clear, I think.
I will change it, yes, it is better.
>> --- a/gdb/doc/gdb.texinfo
>> +++ b/gdb/doc/gdb.texinfo
>> @@ -22267,6 +22267,57 @@ whose bounds are to be changed, @var{lbound}
>> and @var{ubound} are new values  for lower and upper bounds respectively.
>>   @end table
>>   
>> +
>> +A boundary violation is presented to the inferior as a segmentation
>> +fault having SIGCODE 3. @value{GDBN} may display additional
>                                          ^^ Two spaces.
>
>> +information is displayed in this case.
> "...may display additional information is displayed..."?  One of the "display" and "displayed" is redundant here, I think.
I will change to "may display additional information "
>> +                                          On @code{STOP} mode
>> +@value{GDBN} will also display the kind of violation: "upper" or
>> +"lower", bounds, pointer value and the address accessed.
>> +On @code{NOSTOP} no additional information will be presented.
> I suggest to say "In STOP mode" and "In NOSTOP mode".  "In", not "On".
Right!
>
>> +The usual output of a segfault is:
>> +@smallexample
>> +Program received signal SIGSEGV, Segmentation fault
>> +0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
>> +c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
>> +68        value = *(p + len);
>> +@end smallexample
>> +
>> +In case it is a bound violation it will be presented as:
>> +@smallexample
>> +Program received signal SIGSEGV, Segmentation fault upper bound
>> +violation - bounds @{lbound = 0x603010, ubound = 0x603023@} accessing
>> +0x60302f.
>> +0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
>> +c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
>> +68        value = *(p + len);
>> +@end smallexample
> Why do we need to show here the output when no bound violation happened?
>
> Actually, why not move this description and the example to the "Signals" node?  If I were a user who received such a notification, the "Signals" node is where I would look for the explanations first.
I will move it there. About the example I wanted to show where the 
change will be placed. If you consider that this is superfluous, no 
issue in removing.

Will the snippet bellow be better?

Program received signal SIGSEGV, Segmentation fault upper bound
violation - bounds @{lbound = 0x603010, ubound = 0x603023@} accessing
0x60302f.

> Thanks.

Thanks and regards,
-Fred
Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Christian Lamprechter
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: FW: [PATCH V4 6/6] Intel MPX bound violation handling.
  2016-01-21 17:34       ` FW: " Walfred Tedeschi
@ 2016-01-21 17:51         ` Eli Zaretskii
  2016-01-21 18:06           ` Pedro Alves
  0 siblings, 1 reply; 15+ messages in thread
From: Eli Zaretskii @ 2016-01-21 17:51 UTC (permalink / raw)
  To: Walfred Tedeschi; +Cc: palves, brobecker, gdb-patches

> Date: Thu, 21 Jan 2016 18:34:12 +0100
> From: Walfred Tedeschi <walfred.tedeschi@intel.com>
> 
> >> +The usual output of a segfault is:
> >> +@smallexample
> >> +Program received signal SIGSEGV, Segmentation fault
> >> +0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
> >> +c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
> >> +68        value = *(p + len);
> >> +@end smallexample
> >> +
> >> +In case it is a bound violation it will be presented as:
> >> +@smallexample
> >> +Program received signal SIGSEGV, Segmentation fault upper bound
> >> +violation - bounds @{lbound = 0x603010, ubound = 0x603023@} accessing
> >> +0x60302f.
> >> +0x0000000000400d7c in upper (p=0x603010, a=0x603030, b=0x603050,
> >> +c=0x603070, d=0x603090, len=7) at i386-mpx-sigsegv.c:68
> >> +68        value = *(p + len);
> >> +@end smallexample
> > Why do we need to show here the output when no bound violation happened?
> >
> > Actually, why not move this description and the example to the "Signals" node?  If I were a user who received such a notification, the "Signals" node is where I would look for the explanations first.
> I will move it there. About the example I wanted to show where the 
> change will be placed. If you consider that this is superfluous, no 
> issue in removing.

If you move the description there, showing both examples would be
good.  In the place where you put it, only the bounds violation is
described, so it is strange to have there the display without bounds
violation.

> Will the snippet bellow be better?
> 
> Program received signal SIGSEGV, Segmentation fault upper bound
> violation - bounds @{lbound = 0x603010, ubound = 0x603023@} accessing
> 0x60302f.

I still think the word "address" should be added after "accessing".

But if no one else thinks it's important, I don't insist.

Thanks.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: FW: [PATCH V4 6/6] Intel MPX bound violation handling.
  2016-01-21 17:51         ` Eli Zaretskii
@ 2016-01-21 18:06           ` Pedro Alves
  2016-01-21 18:22             ` Eli Zaretskii
  2016-01-22  8:38             ` Walfred Tedeschi
  0 siblings, 2 replies; 15+ messages in thread
From: Pedro Alves @ 2016-01-21 18:06 UTC (permalink / raw)
  To: Eli Zaretskii, Walfred Tedeschi; +Cc: palves, brobecker, gdb-patches

On 01/21/2016 05:51 PM, Eli Zaretskii wrote:
>> Date: Thu, 21 Jan 2016 18:34:12 +0100
>> From: Walfred Tedeschi <walfred.tedeschi@intel.com>

>> Program received signal SIGSEGV, Segmentation fault upper bound
>> violation - bounds @{lbound = 0x603010, ubound = 0x603023@} accessing
>> 0x60302f.
> 
> I still think the word "address" should be added after "accessing".
> 
> But if no one else thinks it's important, I don't insist.

I'd think that accessing 0x60302f would be the most important
information here, and so it should be printed before the bounds even.
Say:

 Program received signal SIGSEGV, Segmentation fault
 Upper bound violation while accessing address 0x60302f
 Bounds: {lbound = 0x603010, ubound = 0x603023}

Note we still repeat the string "bound" 4 times.  Maybe we
could reduce that:

 Program received signal SIGSEGV, Segmentation fault
 Upper bound violation while accessing address 0x60302f
 Bounds: [lower = 0x603010, upper = 0x603023]

But maybe lbound/ubound already have defined meaning to
the user.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: FW: [PATCH V4 6/6] Intel MPX bound violation handling.
  2016-01-21 18:06           ` Pedro Alves
@ 2016-01-21 18:22             ` Eli Zaretskii
  2016-01-22  8:38             ` Walfred Tedeschi
  1 sibling, 0 replies; 15+ messages in thread
From: Eli Zaretskii @ 2016-01-21 18:22 UTC (permalink / raw)
  To: Pedro Alves; +Cc: walfred.tedeschi, brobecker, gdb-patches

> Date: Thu, 21 Jan 2016 18:06:06 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: palves@redhat.com, brobecker@adacore.com, gdb-patches@sourceware.org
> 
>  Program received signal SIGSEGV, Segmentation fault
>  Upper bound violation while accessing address 0x60302f
>  Bounds: {lbound = 0x603010, ubound = 0x603023}
> 
> Note we still repeat the string "bound" 4 times.  Maybe we
> could reduce that:
> 
>  Program received signal SIGSEGV, Segmentation fault
>  Upper bound violation while accessing address 0x60302f
>  Bounds: [lower = 0x603010, upper = 0x603023]
> 
> But maybe lbound/ubound already have defined meaning to
> the user.

Both variants are fine, IMO.

Thanks.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: FW: [PATCH V4 6/6] Intel MPX bound violation handling.
  2016-01-21 18:06           ` Pedro Alves
  2016-01-21 18:22             ` Eli Zaretskii
@ 2016-01-22  8:38             ` Walfred Tedeschi
  1 sibling, 0 replies; 15+ messages in thread
From: Walfred Tedeschi @ 2016-01-22  8:38 UTC (permalink / raw)
  To: Pedro Alves, Eli Zaretskii; +Cc: brobecker, gdb-patches

Am 1/21/2016 um 7:06 PM schrieb Pedro Alves:
> On 01/21/2016 05:51 PM, Eli Zaretskii wrote:
>>> Date: Thu, 21 Jan 2016 18:34:12 +0100
>>> From: Walfred Tedeschi <walfred.tedeschi@intel.com>
>
>>> Program received signal SIGSEGV, Segmentation fault upper bound
>>> violation - bounds @{lbound = 0x603010, ubound = 0x603023@} accessing
>>> 0x60302f.
>>
>> I still think the word "address" should be added after "accessing".
>>
>> But if no one else thinks it's important, I don't insist.
>
> I'd think that accessing 0x60302f would be the most important
> information here, and so it should be printed before the bounds even.
> Say:
>
>   Program received signal SIGSEGV, Segmentation fault
>   Upper bound violation while accessing address 0x60302f
>   Bounds: {lbound = 0x603010, ubound = 0x603023}
>
> Note we still repeat the string "bound" 4 times.  Maybe we
> could reduce that:
>
>   Program received signal SIGSEGV, Segmentation fault
>   Upper bound violation while accessing address 0x60302f
>   Bounds: [lower = 0x603010, upper = 0x603023]
>
> But maybe lbound/ubound already have defined meaning to
> the user.

I will pick Pedro's suggestion, looks nicer to the user.
Also adding the documentation lines to the Signal part.

>
> Thanks,
> Pedro Alves
>

Thanks for the review and additions!
-Fred

Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Christian Lamprechter
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2016-01-22  8:38 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-21 14:48 [PATCH V4 0/6] Intel MPX bound violation support Walfred Tedeschi
2016-01-21 14:48 ` [PATCH V4 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
2016-01-21 14:49 ` [PATCH V4 5/6] Adaptation of siginfo fixup for the new bnd fields Walfred Tedeschi
2016-01-21 14:49 ` [PATCH V4 1/6] Merge gdb and gdbserver implementations for siginfo Walfred Tedeschi
2016-01-21 15:05   ` Pedro Alves
2016-01-21 14:49 ` [PATCH V4 4/6] Add bound related fields to the siginfo structure Walfred Tedeschi
2016-01-21 14:49 ` [PATCH V4 6/6] Intel MPX bound violation handling Walfred Tedeschi
2016-01-21 16:23   ` Eli Zaretskii
     [not found]     ` <AC542571535E904D8E8ADAE745D60B194452CD61@IRSMSX104.ger.corp.intel.com>
2016-01-21 17:34       ` FW: " Walfred Tedeschi
2016-01-21 17:51         ` Eli Zaretskii
2016-01-21 18:06           ` Pedro Alves
2016-01-21 18:22             ` Eli Zaretskii
2016-01-22  8:38             ` Walfred Tedeschi
2016-01-21 14:49 ` [PATCH V4 2/6] Prepararion for new siginfo on Linux Walfred Tedeschi
2016-01-21 15:05   ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).