This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb(refs/for/public/siginfo_mpx)] Synchronize siginfo type described in GDB with the kernel and glibc ones.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=50728ed21731a3bd8471f92a21b67d1e28ae0e3e

commit 50728ed21731a3bd8471f92a21b67d1e28ae0e3e
Author: Walfred Tedeschi <walfred.tedeschi@intel.com>
Date:   Wed Dec 2 10:45:09 2015 +0100

    Synchronize siginfo type described in GDB with the kernel and glibc ones.
    
    New kernel and glibc patches have introduced fields in the
    segmentation fault fields.
    
    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
    
    2015-07-21  Walfred Tedeschi  <walfred.tedeschi@intel.com>
    
    	* linux-tdep.c (linux_get_siginfo_type): Add the _addr_bnd
    	structure to the siginfo.
    
    Change-Id: Ieba07168e7d5a967d9fade7477b3e5ded7d34d74
    Signed-off-by: Walfred Tedeschi <walfred.tedeschi@intel.com>

Diff:
---
 gdb/Makefile.in               |   7 +-
 gdb/amd64-linux-nat.c         | 434 +------------------------------------
 gdb/config/i386/linux64.mh    |   2 +-
 gdb/gdbserver/Makefile.in     |   3 +
 gdb/gdbserver/configure.srv   |   2 +-
 gdb/gdbserver/linux-x86-low.c | 412 +----------------------------------
 gdb/nat/x86-siginfo.c         | 485 ++++++++++++++++++++++++++++++++++++++++++
 gdb/nat/x86-siginfo.h         |  37 ++++
 8 files changed, 546 insertions(+), 836 deletions(-)

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 14ad405..8d3209e 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -985,7 +985,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/x86-siginfo.h \
 nat/linux-namespaces.h arch/arm.h common/gdb_sys_time.h arch/aarch64-insn.h
 
 # Header files that already have srcdir in them, or which are in objdir.
@@ -2335,6 +2335,11 @@ x86-linux-dregs.o: ${srcdir}/nat/x86-linux-dregs.c
 	$(COMPILE) $(srcdir)/nat/x86-linux-dregs.c
 	$(POSTCOMPILE)
 
+
+x86-siginfo.o: ${srcdir}/nat/x86-siginfo.c
+	$(COMPILE) $(srcdir)/nat/x86-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 397f664..862b452 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/x86-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,
 }
 
 
-/* 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
@@ -733,38 +331,22 @@ static int
 amd64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
 {
   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
+  struct nat_siginfo *nat_sig = (struct nat_siginfo *) inf;
 
   /* 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;
-    }
+  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
+      return amd64_linux_siginfo_fixup_low (native, inf , direction,
+					    COMPAT32_FIXUP);
   /* 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_low (native, inf , direction,
+					    X32_FIXUP);
   else
     return 0;
 }
-
+
 
 /* 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..6d4748b 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 x86-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 97e1e62..cc8070d 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -595,6 +595,9 @@ arm.o: ../arch/arm.c
 x86-dregs.o: ../nat/x86-dregs.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
+x86-siginfo.o: ../nat/x86-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 e854110..63b9590 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -333,7 +333,7 @@ case "${target}" in
 			srv_linux_thread_db=yes
 			;;
   x86_64-*-linux*)	srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
-			srv_tgtobj="$srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o"
+			srv_tgtobj="$srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o x86-siginfo.o i387-fp.o"
 			srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o"
 			srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o"
 			srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index 89ec4e5..7626f32 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -26,6 +26,7 @@
 #include "x86-low.h"
 #include "x86-xstate.h"
 #include "nat/gdb_ptrace.h"
+#include "nat/x86-siginfo.h"
 
 #include "gdb_proc_service.h"
 /* Don't include elf/common.h if linux/elf.h got included by
@@ -676,391 +677,6 @@ x86_debug_reg_state (pid_t pid)
 
 #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
@@ -1079,30 +695,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_low (native, inf , direction,
+					    COMPAT32_FIXUP);
   /* 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_low (native, inf , direction,
+					  X32_FIXUP);
 #endif
 
   return 0;
diff --git a/gdb/nat/x86-siginfo.c b/gdb/nat/x86-siginfo.c
new file mode 100644
index 0000000..595f66b
--- /dev/null
+++ b/gdb/nat/x86-siginfo.c
@@ -0,0 +1,485 @@
+/* Low-level siginfo manipulation (i386 and x86-64).
+
+   Copyright (C) 2002-2015 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 "x86-siginfo.h"
+
+/* 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.  With the presence of possible different
+   fields for host and target we have to guarantee that we use the
+   Also, the first step is to make a copy from the original bits to the
+   internal structure which is the super set. */
+
+/* These types below (native_*) define a siginfo type that is layout
+   the most complete siginfo available for the architecture.  */
+
+
+
+/* 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;
+      short int _addr_lsb;
+      struct
+      {
+	unsigned int _lower;
+	unsigned int _upper;
+      } si_addr_bnd;
+    } _sigfault;
+
+    /* SIGPOLL */
+    struct
+    {
+      int _band;
+      int _fd;
+    } _sigpoll;
+  } _sifields;
+} compat_siginfo_t;
+
+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;
+
+    /* MPX fields are not needed here; X32 not supported.  */
+    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS.  */
+    struct
+    {
+      unsigned int _addr;
+      unsigned int _addr_lsb;
+    } _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_addr_lsb _sifields._sigfault._addr_lsb
+#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;
+	  to->cpt_si_addr_lsb = (short) from->si_addr_lsb;
+	  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;
+	  to->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;
+	  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;
+	  to->cpt_si_addr_lsb = (short) from->si_addr_lsb;
+	  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;
+	  to->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;
+	  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, copy from NATIVE to
+   INF.  */
+
+int
+amd64_linux_siginfo_fixup_low (siginfo_t *native, gdb_byte *inf,
+			       int direction,
+			       enum amd64_siginfo_fixup_mode mode)
+{
+
+  if (mode == COMPAT32_FIXUP)
+    {
+      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;
+    }
+  /* No fixup for native x32 GDB.  */
+  else if (mode == X32_FIXUP)
+    {
+      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;
+    }
+  else
+    return 0;
+}
diff --git a/gdb/nat/x86-siginfo.h b/gdb/nat/x86-siginfo.h
new file mode 100644
index 0000000..92fdd92
--- /dev/null
+++ b/gdb/nat/x86-siginfo.h
@@ -0,0 +1,37 @@
+/* Common code for x86 siginfo handling.
+
+   Copyright (C) 2015 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 X86_SIGINFO_H
+#define X86_SIGINFO_H 1
+
+
+enum amd64_siginfo_fixup_mode
+{
+  X32_FIXUP = 1,
+  COMPAT32_FIXUP = 2,
+  UNKNOWN
+};
+
+int
+amd64_linux_siginfo_fixup_low (siginfo_t *native, gdb_byte *inf,
+			       int direction,
+			       enum amd64_siginfo_fixup_mode mode);
+
+
+#endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]