public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH V3 3/6] Use linux_get_siginfo_type_with_fields for x86.
  2016-01-18  8:25 [PATCH V3 0/6] Intel MPX bound violation support Walfred Tedeschi
@ 2016-01-18  8:25 ` Walfred Tedeschi
  2016-01-20 18:57   ` Pedro Alves
  2016-01-18  8:25 ` [PATCH V3 2/6] Prepararion for new siginfo on Linux Walfred Tedeschi
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Walfred Tedeschi @ 2016-01-18  8:25 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
	function linux_get_siginfo_type_with_fields public.
	* linux-tdep.c (linux_get_siginfo_type_with_fields): Make
	function linux_get_siginfo_type_with_fields public.
	* i386-linux-tdep.h (x86_get_siginfo_type_with_fields): New
	function.
	* amd64-linux-tdep.c (amd64_linux_init_abi_common): Add
	x86_get_siginfo_type_with_fields for the amd64 abi.
	* i386-linux-tdep.c (x86_get_siginfo_type_with_fields): 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       | 5 +++++
 5 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index b948ea7..55aad81 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_get_siginfo_type_with_fields);
 }
 
 static void
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 1e491e7..353688b 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_get_siginfo_type_with_fields (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_get_siginfo_type_with_fields);
 }
 
 /* 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..fbd0817 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -34,6 +34,11 @@ 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] 11+ messages in thread

* [PATCH V3 2/6] Prepararion for new siginfo on Linux.
  2016-01-18  8:25 [PATCH V3 0/6] Intel MPX bound violation support Walfred Tedeschi
  2016-01-18  8:25 ` [PATCH V3 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
@ 2016-01-18  8:25 ` Walfred Tedeschi
  2016-01-20 18:56   ` Pedro Alves
  2016-01-18  8:26 ` [PATCH V3 4/6] Add bound related fields to the siginfo structure Walfred Tedeschi
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Walfred Tedeschi @ 2016-01-18  8:25 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] 11+ messages in thread

* [PATCH V3 0/6] Intel MPX bound violation support.
@ 2016-01-18  8:25 Walfred Tedeschi
  2016-01-18  8:25 ` [PATCH V3 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Walfred Tedeschi @ 2016-01-18  8:25 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
and usage.

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


Pedro,

Thanks for your patch that has fixed evaluations while stopping,
but still not stopped.  That has solved the issue also here
while evaluating the siginfo.


Best regards,
-Fred



Walfred Tedeschi (6):
  Merges gdb and gdbserver implementation 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/amd64-linux-nat.c                           | 431 +-----------------
 gdb/amd64-linux-tdep.c                          |   5 +
 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                           |  54 +++
 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                                |  15 +
 gdb/nat/amd64-linux-siginfo.c                   | 570 ++++++++++++++++++++++++
 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 ++++++
 24 files changed, 1300 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] 11+ messages in thread

* [PATCH V3 4/6] Add bound related fields to the siginfo structure.
  2016-01-18  8:25 [PATCH V3 0/6] Intel MPX bound violation support Walfred Tedeschi
  2016-01-18  8:25 ` [PATCH V3 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
  2016-01-18  8:25 ` [PATCH V3 2/6] Prepararion for new siginfo on Linux Walfred Tedeschi
@ 2016-01-18  8:26 ` Walfred Tedeschi
  2016-01-20 18:57   ` Pedro Alves
  2016-01-18  8:26 ` [PATCH V3 5/6] Adaptation of siginfo fixup for the new bnd fields Walfred Tedeschi
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: Walfred Tedeschi @ 2016-01-18  8:26 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] 11+ messages in thread

* [PATCH V3 5/6] Adaptation of siginfo fixup for the new bnd fields.
  2016-01-18  8:25 [PATCH V3 0/6] Intel MPX bound violation support Walfred Tedeschi
                   ` (2 preceding siblings ...)
  2016-01-18  8:26 ` [PATCH V3 4/6] Add bound related fields to the siginfo structure Walfred Tedeschi
@ 2016-01-18  8:26 ` Walfred Tedeschi
  2016-01-18  8:26 ` [PATCH V3 6/6] Intel MPX bound violation handling Walfred Tedeschi
  2016-01-18  8:26 ` [PATCH V3 1/6] Merges gdb and gdbserver implementation for siginfo Walfred Tedeschi
  5 siblings, 0 replies; 11+ messages in thread
From: Walfred Tedeschi @ 2016-01-18  8:26 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 7045ff2..ac5c138 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
 
@@ -190,54 +285,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;
 	}
     }
@@ -247,57 +346,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));
 }
 
 /*  Converts the system provided siginfo into compatible x32 siginfo.  */
@@ -305,56 +409,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;
 	}
     }
@@ -365,59 +473,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 11738fb..e6de70b 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] 11+ messages in thread

* [PATCH V3 1/6] Merges gdb and gdbserver implementation for siginfo.
  2016-01-18  8:25 [PATCH V3 0/6] Intel MPX bound violation support Walfred Tedeschi
                   ` (4 preceding siblings ...)
  2016-01-18  8:26 ` [PATCH V3 6/6] Intel MPX bound violation handling Walfred Tedeschi
@ 2016-01-18  8:26 ` Walfred Tedeschi
  2016-01-20 15:42   ` Pedro Alves
  5 siblings, 1 reply; 11+ messages in thread
From: Walfred Tedeschi @ 2016-01-18  8:26 UTC (permalink / raw)
  To: palves, eliz, brobecker; +Cc: gdb-patches, Walfred Tedeschi

The compatible siginfo handling from amd64-linux-nat.c and
gdbserver/linux-x86-low were extracted it into 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.
	 Add native object files rule for
	(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)
	(and collateral structures): 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/mad64-linux-siginfo.h".
	(compat_siginfo_from_siginfo, siginfo_from_compat_siginfo)
	(compat_x32_siginfo_from_siginfo, siginfo_from_compat_x32_siginfo)
	(and collateral structures): Move to 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 | 458 ++++++++++++++++++++++++++++++++++++++++++
 gdb/nat/amd64-linux-siginfo.h |  44 ++++
 8 files changed, 527 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..7045ff2
--- /dev/null
+++ b/gdb/nat/amd64-linux-siginfo.c
@@ -0,0 +1,458 @@
+/* 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
+
+/*  Converts 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;
+	}
+    }
+}
+
+/* Converts 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;
+	}
+    }
+}
+
+/*  Converts 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;
+	}
+    }
+}
+
+/* Converts 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..11738fb
--- /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] 11+ messages in thread

* [PATCH V3 6/6] Intel MPX bound violation handling.
  2016-01-18  8:25 [PATCH V3 0/6] Intel MPX bound violation support Walfred Tedeschi
                   ` (3 preceding siblings ...)
  2016-01-18  8:26 ` [PATCH V3 5/6] Adaptation of siginfo fixup for the new bnd fields Walfred Tedeschi
@ 2016-01-18  8:26 ` Walfred Tedeschi
  2016-01-18  8:26 ` [PATCH V3 1/6] Merges gdb and gdbserver implementation for siginfo Walfred Tedeschi
  5 siblings, 0 replies; 11+ messages in thread
From: Walfred Tedeschi @ 2016-01-18  8:26 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.

---
 gdb/amd64-linux-tdep.c                          |   3 +
 gdb/doc/gdb.texinfo                             |  51 ++++++++++
 gdb/gdbarch.c                                   |  32 ++++++
 gdb/gdbarch.h                                   |  11 ++
 gdb/gdbarch.sh                                  |   6 ++
 gdb/i386-linux-tdep.c                           |  46 +++++++++
 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 ++++++++++++++++++++++++
 14 files changed, 592 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/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 55aad81..168f7e1 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -1840,6 +1840,9 @@ 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_get_siginfo_type_with_fields);
+  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 353688b..7485de4 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,9 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
                                   i386_linux_get_syscall_number);
 
   set_gdbarch_get_siginfo_type (gdbarch, x86_get_siginfo_type_with_fields);
+  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] 11+ messages in thread

* Re: [PATCH V3 1/6] Merges gdb and gdbserver implementation for siginfo.
  2016-01-18  8:26 ` [PATCH V3 1/6] Merges gdb and gdbserver implementation for siginfo Walfred Tedeschi
@ 2016-01-20 15:42   ` Pedro Alves
  0 siblings, 0 replies; 11+ messages in thread
From: Pedro Alves @ 2016-01-20 15:42 UTC (permalink / raw)
  To: Walfred Tedeschi, eliz, brobecker; +Cc: gdb-patches

In $subject: please use imperative "Merge".  Also, "implementations",
plural.  (Please drop periods in subject lines while at it).

On 01/18/2016 08:25 AM, Walfred Tedeschi wrote:
> The compatible siginfo handling from amd64-linux-nat.c and
> gdbserver/linux-x86-low were extracted it into a new file
> nat/amd64-linux-siginfo.c.

I suggest:

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.
> 	 Add native object files rule for

This "Add native..." sentence looks stray/unfinished.  Also, if it stays,
please align it with a single tab (you have an extra suprious space).

> 	(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)
> 	(and collateral structures): Move to nat/amd64-linux-siginfo.c.

Please spell out the structures names instead of the "and collateral
structures" bit.

> 
> 
> 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/mad64-linux-siginfo.h".

Typo "mad64".

> 	(compat_siginfo_from_siginfo, siginfo_from_compat_siginfo)
> 	(compat_x32_siginfo_from_siginfo, siginfo_from_compat_x32_siginfo)
> 	(and collateral structures): Move to nat/amd64-linux-siginfo.c.

See above.

> 	* Makefile.in (amd64-linux-siginfo.o:): New rule.


> +
> +/*  Converts the system provided siginfo into compatible siginfo.  */

Say "Convert".  Also, please leave an empty line between intro command
and function definition.

> +static void
> +compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
> +{

> +
> +/* Converts the compatible siginfo into system siginfo.  */
> +static void
> +siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)

Ditto.

> +/*  Converts the system provided siginfo into compatible x32 siginfo.  */
> +static void
> +compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to,
> +				 siginfo_t *from)

Ditto.


> +
> +/* Converts the compatible x32 siginfo into system siginfo.  */
> +static void
> +siginfo_from_compat_x32_siginfo (siginfo_t *to,
> +				 compat_x32_siginfo_t *from)

Ditto.

Otherwise OK.

Thanks,
Pedro Alves

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

* Re: [PATCH V3 2/6] Prepararion for new siginfo on Linux.
  2016-01-18  8:25 ` [PATCH V3 2/6] Prepararion for new siginfo on Linux Walfred Tedeschi
@ 2016-01-20 18:56   ` Pedro Alves
  0 siblings, 0 replies; 11+ messages in thread
From: Pedro Alves @ 2016-01-20 18:56 UTC (permalink / raw)
  To: Walfred Tedeschi, eliz, brobecker; +Cc: gdb-patches

On 01/18/2016 08:25 AM, Walfred Tedeschi wrote:
> 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.  */

"a specific"

>  
>  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 used to define the extra fields of the siginfo type used by
   an architecture.  */

> +enum linux_siginfo_extra_field_values
> +{
> +  /* Add bound fields into the segmentation fault fields.  */

"segmentation fault field."

> +  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);
> +

Line too long.


>  typedef char *(*linux_collect_thread_registers_ftype) (const struct regcache *,
>  						       ptid_t,
>  						       bfd *, char *, int *,
> 

Otherwise OK.

Thanks,
Pedro Alves

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

* Re: [PATCH V3 4/6] Add bound related fields to the siginfo structure.
  2016-01-18  8:26 ` [PATCH V3 4/6] Add bound related fields to the siginfo structure Walfred Tedeschi
@ 2016-01-20 18:57   ` Pedro Alves
  0 siblings, 0 replies; 11+ messages in thread
From: Pedro Alves @ 2016-01-20 18:57 UTC (permalink / raw)
  To: Walfred Tedeschi, eliz, brobecker; +Cc: gdb-patches

This doesn't seem to address any of the comments I made to this patch in v2?

Thanks,
Pedro Alves

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

* Re: [PATCH V3 3/6] Use linux_get_siginfo_type_with_fields for x86.
  2016-01-18  8:25 ` [PATCH V3 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
@ 2016-01-20 18:57   ` Pedro Alves
  0 siblings, 0 replies; 11+ messages in thread
From: Pedro Alves @ 2016-01-20 18:57 UTC (permalink / raw)
  To: Walfred Tedeschi, eliz, brobecker; +Cc: gdb-patches

On 01/18/2016 08:25 AM, Walfred Tedeschi wrote:
> 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
> 	function linux_get_siginfo_type_with_fields public.

As mentioned in the v1 review, it's linkage you're changing, not
class visibility.  Drop redundant name reference.  Thus:

 	* linux-tdep.h (linux_get_siginfo_type_with_fields): Make
 	extern.


> 	* linux-tdep.c (linux_get_siginfo_type_with_fields): Make
> 	function linux_get_siginfo_type_with_fields public.

Likewise.

> 	* i386-linux-tdep.h (x86_get_siginfo_type_with_fields): New
> 	function.
> 	* amd64-linux-tdep.c (amd64_linux_init_abi_common): Add
> 	x86_get_siginfo_type_with_fields for the amd64 abi.
> 	* i386-linux-tdep.c (x86_get_siginfo_type_with_fields): 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       | 5 +++++
>  5 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
> index b948ea7..55aad81 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_get_siginfo_type_with_fields);
>  }
>  
>  static void
> diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
> index 1e491e7..353688b 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_get_siginfo_type_with_fields (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_get_siginfo_type_with_fields);
>  }
>  
>  /* 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);

As I mentioned in the previous review, "with_fields" is implementation detail.
Callers of this function shouldn't have to care.  Can you rename this
to x86_linux_get_siginfo_type please?  (Note the "linux").


> +
>  #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..fbd0817 100644
> --- a/gdb/linux-tdep.h
> +++ b/gdb/linux-tdep.h
> @@ -34,6 +34,11 @@ 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);

Function names in declarations shouldn't be at column 0.  Only in
definitions.  Add two leading spaces to the function name, or,
alternatively, break the line before the (, and then add two spaces
to the parameter list.

Thanks,
Pedro Alves

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

end of thread, other threads:[~2016-01-20 18:57 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-18  8:25 [PATCH V3 0/6] Intel MPX bound violation support Walfred Tedeschi
2016-01-18  8:25 ` [PATCH V3 3/6] Use linux_get_siginfo_type_with_fields for x86 Walfred Tedeschi
2016-01-20 18:57   ` Pedro Alves
2016-01-18  8:25 ` [PATCH V3 2/6] Prepararion for new siginfo on Linux Walfred Tedeschi
2016-01-20 18:56   ` Pedro Alves
2016-01-18  8:26 ` [PATCH V3 4/6] Add bound related fields to the siginfo structure Walfred Tedeschi
2016-01-20 18:57   ` Pedro Alves
2016-01-18  8:26 ` [PATCH V3 5/6] Adaptation of siginfo fixup for the new bnd fields Walfred Tedeschi
2016-01-18  8:26 ` [PATCH V3 6/6] Intel MPX bound violation handling Walfred Tedeschi
2016-01-18  8:26 ` [PATCH V3 1/6] Merges gdb and gdbserver implementation for siginfo Walfred Tedeschi
2016-01-20 15:42   ` 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).