diff mbox series

Refactor sigcontextinfo.h

Message ID 20190529182953.23119-1-adhemerval.zanella@linaro.org
State New
Headers show
Series Refactor sigcontextinfo.h | expand

Commit Message

Adhemerval Zanella Netto May 29, 2019, 6:29 p.m. UTC
This patch refactor sigcontextinfo.h header to use SA_SIGINFO as default
for both gmon and debug implementations.  This allows simplify
profil-counter.h on Linux to use a single implementation and remove the
requirements for newer ports to redefine __sigaction/sigaction to use
SIG_SIGINFO.

The GET_PC macro is also changed to return an uintptr_t instead of a void
pointer (it allows easier convertion to integer on ILP32 architecture, such
as x32, without the need to supress compiler warnings).

The patch also requires some refactor of register-dump.h file for some
architectures (to reflect it is called from a sa_sigaction instead of
sa_handler signal context):

   - Alpha, i386, and s390 is straighfoward to take in consideration the
     new argument type.

   - ia64 take in consideration the kernel pass a sigcontext_t struct
     as third argument for sa_sigaction.

   - saprc take in consideration the kernel pass a pt_regs struct
     as third argument for sa_sigaction.

   - m68k dummy function is removed and the FP state is dumped on
     register_dump itself.

   - For SH the register-dump.h file is consolidate on a common implementation
     and the floating-point state is checked based on ownedfp field.

The register_dump does not change its output format in any affected
architecture.

I checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu,
arm-linux-gnueabihf, sparcv9-linux-gnu, sparc64-linux-gnu, powerpc-linux-gnu,
powerpc64-linux-gnu, and powerpc64le-linux-gnu.

I also checked the libSegFault.so through catchsegv on alpha-linux-gnu,
m68k-linux-gnu and sh4-linux-gnu to confirm the output has not changed.

This change is also the last pre-liminar one I would to like to push
before re-sending the BZ#12683 fix.

	* debug/segfault.c (install_handler): Use SA_SIGINFO if defined.
	* sysdeps/generic/profil-counter.h (__profil_counter): Cast to
	uintptr_t.
	(USE_SA_SIGINFO): New define.
	* sysdeps/generic/sigcontextinfo.h (GET_PC): Return aligned cast to
	uintptr_t.
	* sysdeps/mach/hurd/i386/sigcontextinfo.h (GET_PC): Likewise.
	* sysdeps/posix/profil.c (profil_count): Change PC argument to
	uintptr_t.
	(__profil): Use SA_SIGINFO for USE_SA_SIGINFO.
	* sysdeps/posix/sprofil.c (profil_count): Change PCP argument to
	uintptr_t.
	(__sprofil): Use SA_SIGINFO for USE_SA_SIGINFO.
	* sysdeps/unix/sysv/linux/profil-counter.h: New file.
	* sysdeps/unix/sysv/linux/aarch64/profil-counter.h: Remove file.
	* sysdeps/unix/sysv/linux/csky/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/hppa/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/i386/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/ia64/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/nios2/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/riscv/profil-counter.h: Likewise.
	* sysdeps/sysv/linux/s390/s390-32/profil-counter.h: Likewise.
	* sysdeps/sysv/linux/s390/s390-64/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/sh/profil-counter.h: Likewise.
	* sysdeps/unix/sysv/linux/arm/profil-counter.h (__profil_counter):
	Remove function and use generic Linux implementation.
	* sysdeps/unix/sysv/linux/sparc/profil-counter.h: New file.
	* sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h: Remove file.
	* sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h: Likewise.
	* sysdpes/unix/sysv/linux/aarch64/sigcontextinfo.h (SIGCONTEXT,
	GET_PC, __sigaction, sigaction): Remove defines.
	(GET_PC): Handle input as ucontext_t and return the result as
	uintptr_t.
	* sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/arm/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/csky/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/i386/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/s390/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/sh/sigcontextinfo.h: Likewise.
	* sysdeps/sysv/linux/sparc/sparc32/sigcontextinfo.h: Likewise.
	* sysdeps/sysv/linux/sparc/sparc64/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h: Likewise.
	* sysdeps/unix/sysv/linux/alpha/register-dump.h (register_dump):
	Handle CTX argument as ucontext_t.
	* sysdeps/unix/sysv/linux/i386/register-dump.h: Likewise.
	Likewise.
	* sysdeps/unix/sysv/linux/m68k/register-dump.h: Likewise.
	* sysdeps/sysv/linux/s390/s390-32/register-dump.h: Likewise.
	* sysdeps/sysv/linux/s390/s390-64/register-dump.h: Likewise.
	* sysdeps/unix/sysv/linux/sh/register-dump.h: New file.
	* sysdeps/unix/sysv/linux/sh/sh4/register-dump.h: Remove File.
	* sysdeps/unix/sysv/linux/sh/sh3/register-dump.h: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h: Likewise.
---
 debug/segfault.c                              |  14 +-
 sysdeps/generic/profil-counter.h              |   2 +-
 sysdeps/generic/sigcontextinfo.h              |   2 +-
 sysdeps/mach/hurd/i386/sigcontextinfo.h       |   2 +-
 sysdeps/posix/profil.c                        |  19 +-
 sysdeps/posix/sprofil.c                       |  25 +-
 .../unix/sysv/linux/aarch64/profil-counter.h  |  20 --
 .../unix/sysv/linux/aarch64/sigcontextinfo.h  |  15 +-
 sysdeps/unix/sysv/linux/alpha/register-dump.h | 283 +++++++++++-------
 .../unix/sysv/linux/alpha/sigcontextinfo.h    |   6 +-
 sysdeps/unix/sysv/linux/arm/profil-counter.h  |  14 +-
 sysdeps/unix/sysv/linux/arm/sigcontextinfo.h  |  22 +-
 sysdeps/unix/sysv/linux/csky/profil-counter.h |  31 --
 sysdeps/unix/sysv/linux/csky/sigcontextinfo.h |  16 +-
 .../{profil-counter.h => sigcontextinfo.h}    |  12 +-
 sysdeps/unix/sysv/linux/i386/profil-counter.h |  31 --
 sysdeps/unix/sysv/linux/i386/register-dump.h  | 262 ++++++++--------
 sysdeps/unix/sysv/linux/i386/sigcontextinfo.h |   4 +-
 sysdeps/unix/sysv/linux/ia64/profil-counter.h |  31 --
 sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h |   9 +-
 sysdeps/unix/sysv/linux/m68k/register-dump.h  | 117 ++++----
 sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h |   4 +-
 .../sysv/linux/microblaze/profil-counter.h    |   2 -
 .../sysv/linux/microblaze/sigcontextinfo.h    |   4 +-
 sysdeps/unix/sysv/linux/mips/profil-counter.h |   2 -
 sysdeps/unix/sysv/linux/mips/sigcontextinfo.h |  15 +-
 .../unix/sysv/linux/nios2/profil-counter.h    |   2 -
 .../unix/sysv/linux/nios2/sigcontextinfo.h    |  19 +-
 .../unix/sysv/linux/powerpc/profil-counter.h  |   2 -
 .../unix/sysv/linux/powerpc/sigcontextinfo.h  |   9 +-
 .../sysv/linux/{x86_64 => }/profil-counter.h  |  13 +-
 .../unix/sysv/linux/riscv/profil-counter.h    |  31 --
 .../unix/sysv/linux/riscv/sigcontextinfo.h    |   4 +-
 .../sysv/linux/s390/s390-32/profil-counter.h  |  26 --
 .../sysv/linux/s390/s390-32/register-dump.h   |  38 +--
 .../sysv/linux/s390/s390-64/profil-counter.h  |  26 --
 .../sysv/linux/s390/s390-64/register-dump.h   |  38 +--
 sysdeps/unix/sysv/linux/s390/sigcontextinfo.h |  10 +-
 sysdeps/unix/sysv/linux/sh/profil-counter.h   |  32 --
 .../sysv/linux/sh/{sh4 => }/register-dump.h   | 118 ++++----
 .../unix/sysv/linux/sh/sh3/register-dump.h    | 150 ----------
 sysdeps/unix/sysv/linux/sh/sigcontextinfo.h   |   4 +-
 .../sparc/{sparc64 => }/profil-counter.h      |   8 +-
 .../sysv/linux/sparc/sparc32/profil-counter.h |  28 --
 .../sysv/linux/sparc/sparc32/register-dump.h  |  36 ++-
 .../sysv/linux/sparc/sparc32/sigcontextinfo.h |  37 ++-
 .../sysv/linux/sparc/sparc64/register-dump.h  |  42 ++-
 .../sysv/linux/sparc/sparc64/sigcontextinfo.h |  41 ++-
 .../unix/sysv/linux/x86_64/sigcontextinfo.h   |   7 +-
 49 files changed, 696 insertions(+), 989 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/aarch64/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/csky/profil-counter.h
 rename sysdeps/unix/sysv/linux/hppa/{profil-counter.h => sigcontextinfo.h} (77%)
 delete mode 100644 sysdeps/unix/sysv/linux/i386/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/microblaze/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/mips/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/nios2/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/powerpc/profil-counter.h
 rename sysdeps/unix/sysv/linux/{x86_64 => }/profil-counter.h (67%)
 delete mode 100644 sysdeps/unix/sysv/linux/riscv/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h
 delete mode 100644 sysdeps/unix/sysv/linux/sh/profil-counter.h
 rename sysdeps/unix/sysv/linux/sh/{sh4 => }/register-dump.h (62%)
 delete mode 100644 sysdeps/unix/sysv/linux/sh/sh3/register-dump.h
 rename sysdeps/unix/sysv/linux/sparc/{sparc64 => }/profil-counter.h (88%)
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h
diff mbox series

Patch

diff --git a/debug/segfault.c b/debug/segfault.c
index bd1008d9af..1782211fec 100644
--- a/debug/segfault.c
+++ b/debug/segfault.c
@@ -35,6 +35,10 @@ 
    passed up by the signal handler.  */
 #include <sigcontextinfo.h>
 
+#ifdef SA_SIGINFO
+# define SIGCONTEXT siginfo_t *info, void *
+#endif
+
 /* Get code to possibly dump the content of all registers.  */
 #include <register-dump.h>
 
@@ -148,9 +152,15 @@  install_handler (void)
   const char *sigs = getenv ("SEGFAULT_SIGNALS");
   const char *name;
 
-  sa.sa_handler = (void *) catch_segfault;
+#ifdef SA_SIGINFO
+  sa.sa_sigaction = catch_segfault;
+  sa.sa_flags = SA_SIGINFO;
+#else
+  sa.sa_handler = (void*) catch_segfault;
+  sa.sa_flags = 0;
+#endif
   sigemptyset (&sa.sa_mask);
-  sa.sa_flags = SA_RESTART;
+  sa.sa_flags |= SA_RESTART;
 
   /* Maybe we are expected to use an alternative stack.  */
   if (getenv ("SEGFAULT_USE_ALTSTACK") != 0)
diff --git a/sysdeps/generic/profil-counter.h b/sysdeps/generic/profil-counter.h
index 6d3164e101..02de4f795f 100644
--- a/sysdeps/generic/profil-counter.h
+++ b/sysdeps/generic/profil-counter.h
@@ -22,5 +22,5 @@ 
 static void
 __profil_counter (int signr, int code, struct sigcontext *scp)
 {
-  profil_count ((void *) scp->sc_pc);
+  profil_count ((uintptr_t) scp->sc_pc);
 }
diff --git a/sysdeps/generic/sigcontextinfo.h b/sysdeps/generic/sigcontextinfo.h
index ff63a09043..b2ef5ea457 100644
--- a/sysdeps/generic/sigcontextinfo.h
+++ b/sysdeps/generic/sigcontextinfo.h
@@ -18,4 +18,4 @@ 
 
 /* In general we cannot provide any information.  */
 #define SIGCONTEXT struct sigcontext *
-#define GET_PC(ctx)	((void *) 0)
+#define GET_PC(ctx)	((uintptr_t) 0)
diff --git a/sysdeps/mach/hurd/i386/sigcontextinfo.h b/sysdeps/mach/hurd/i386/sigcontextinfo.h
index 65bf12976d..016ea4680f 100644
--- a/sysdeps/mach/hurd/i386/sigcontextinfo.h
+++ b/sysdeps/mach/hurd/i386/sigcontextinfo.h
@@ -16,4 +16,4 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #define SIGCONTEXT struct sigcontext
-#define GET_PC(ctx)	((void *) (ctx).sc_eip)
+#define GET_PC(ctx)	((uintptr_t) (ctx).sc_eip)
diff --git a/sysdeps/posix/profil.c b/sysdeps/posix/profil.c
index 838c36d060..4b8fd9caf1 100644
--- a/sysdeps/posix/profil.c
+++ b/sysdeps/posix/profil.c
@@ -21,6 +21,7 @@ 
 #include <errno.h>
 #include <signal.h>
 #include <sys/time.h>
+#include <stdint.h>
 #include <libc-internal.h>
 #include <sigsetops.h>
 
@@ -36,9 +37,9 @@  static size_t pc_offset;
 static u_int pc_scale;
 
 static inline void
-profil_count (void *pc)
+profil_count (uintptr_t pc)
 {
-  size_t i = (pc - pc_offset - (void *) 0) / 2;
+  size_t i = (pc - pc_offset) / 2;
 
   if (sizeof (unsigned long long int) > sizeof (size_t))
     i = (unsigned long long int) i * pc_scale / 65536;
@@ -71,6 +72,10 @@  __profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 # define oact_ptr &oact
 # define otimer_ptr &otimer
 
+# ifdef SA_SIGINFO
+  oact.sa_flags |= SA_SIGINFO;
+# endif
+
   if (sample_buffer == NULL)
     {
       /* Disable profiling.  */
@@ -104,8 +109,14 @@  __profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
   pc_offset = offset;
   pc_scale = scale;
 
-  act.sa_handler = (sighandler_t) &__profil_counter;
-  act.sa_flags = SA_RESTART;
+#ifdef SA_SIGINFO
+  act.sa_sigaction = __profil_counter;
+  act.sa_flags = SA_SIGINFO;
+#else
+  act.sa_handler = __profil_counter;
+  act.sa_flags = 0;
+#endif
+  act.sa_flags |= SA_RESTART;
   __sigfillset (&act.sa_mask);
   if (__sigaction (SIGPROF, &act, oact_ptr) < 0)
     return -1;
diff --git a/sysdeps/posix/sprofil.c b/sysdeps/posix/sprofil.c
index 3f76bf5174..a9d4a7f3b4 100644
--- a/sysdeps/posix/sprofil.c
+++ b/sysdeps/posix/sprofil.c
@@ -105,10 +105,10 @@  index_to_pc (unsigned long int n, size_t offset, unsigned int scale,
 }
 
 static void
-profil_count (void *pcp, int prof_uint)
+profil_count (uintptr_t pcp, int prof_uint)
 {
   struct region *region, *r = prof_info.last;
-  size_t lo, hi, mid, pc = (unsigned long int) pcp;
+  size_t lo, hi, mid, pc = pcp;
   unsigned long int i;
 
   /* Fast path: pc is in same region as before.  */
@@ -165,13 +165,13 @@  profil_count (void *pcp, int prof_uint)
 }
 
 static inline void
-profil_count_ushort (void *pcp)
+profil_count_ushort (uintptr_t pcp)
 {
   profil_count (pcp, 0);
 }
 
 static inline void
-profil_count_uint (void *pcp)
+profil_count_uint (uintptr_t pcp)
 {
   profil_count (pcp, 1);
 }
@@ -334,11 +334,18 @@  __sprofil (struct prof *profp, int profcnt, struct timeval *tvp,
   prof_info.last = prof_info.region;
 
   /* Install SIGPROF handler.  */
-  if (flags & PROF_UINT)
-    act.sa_handler = (sighandler_t) &__profil_counter_uint;
-  else
-    act.sa_handler = (sighandler_t) &__profil_counter_ushort;
-  act.sa_flags = SA_RESTART;
+#ifdef SA_SIGINFO
+  act.sa_sigaction= flags & PROF_UINT
+		    ? __profil_counter_uint
+		    : __profil_counter_ushort;
+  act.sa_flags = SA_SIGINFO;
+#else
+  act.sa_handler = flags & PROF_UINT
+		   ? (sighandler_t) __profil_counter_uint
+		   : (sighandler_t) __profil_counter_ushort;
+  act.sa_flags = 0;
+#endif
+  act.sa_flags |= SA_RESTART;
   __sigfillset (&act.sa_mask);
   if (__sigaction (SIGPROF, &act, &prof_info.saved_action) < 0)
     return -1;
diff --git a/sysdeps/unix/sysv/linux/aarch64/profil-counter.h b/sysdeps/unix/sysv/linux/aarch64/profil-counter.h
deleted file mode 100644
index 4f8b6501c0..0000000000
--- a/sysdeps/unix/sysv/linux/aarch64/profil-counter.h
+++ /dev/null
@@ -1,20 +0,0 @@ 
-/* Copyright (C) 2009-2019 Free Software Foundation, Inc.
-
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-/* We can use the ix86 version.  */
-#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
index a0b0002c3d..788f16d124 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
@@ -19,17 +19,4 @@ 
 #include <stdint.h>
 #include <sys/ucontext.h>
 
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-#define GET_PC(ctx) ((void *) (uintptr_t) (ctx)->uc_mcontext.pc)
-
-/* There is no reliable way to get the sigcontext unless we use a
-   three-argument signal handler.  */
-#define __sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (__sigaction) (sig, act, oact); \
-})
-
-#define sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (sigaction) (sig, act, oact); \
-})
+#define GET_PC(ctx) ((uintptr_t)(((ucontext_t *) (ctx))->uc_mcontext.pc))
diff --git a/sysdeps/unix/sysv/linux/alpha/register-dump.h b/sysdeps/unix/sysv/linux/alpha/register-dump.h
index 9d55bc0fc5..45dafe0a1f 100644
--- a/sysdeps/unix/sysv/linux/alpha/register-dump.h
+++ b/sysdeps/unix/sysv/linux/alpha/register-dump.h
@@ -16,8 +16,10 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <stddef.h>
 #include <string.h>
+#include <ucontext.h>
+#include <sys/uio.h>
+#include <_itoa.h>
 
 /* We will print the register dump in this format:
 
@@ -48,109 +50,190 @@ 
    TA0: XXXXXXXXXXXXXXXX   TA1: XXXXXXXXXXXXXXXX   TA2: XXXXXXXXXXXXXXXX
 */
 
-#define NREGS (32+32+3)
-
-static const char __attribute__((aligned(8))) regnames[NREGS][8] =
-{
-  "    V0: ", "    T0: ", "    T1: ",
-  "    T2: ", "    T3: ", "    T4: ",
-  "    T5: ", "    T6: ", "    T7: ",
-  "    S0: ", "    S1: ", "    S2: ",
-  "    S3: ", "    S4: ", "    S5: ",
-  "    S6: ", "    A0: ", "    A1: ",
-  "    A2: ", "    A3: ", "    A4: ",
-  "    A5: ", "    T8: ", "    T9: ",
-  "   T10: ", "   T11: ", "    RA: ",
-  "   T12: ", "    AT: ", "    GP: ",
-  "    SP: ", "    PC: ",
-
-  "   FP0: ", "   FP1: ", "   FP2: ",
-  "   FP3: ", "   FP4: ", "   FP5: ",
-  "   FP6: ", "   FP7: ", "   FP8: ",
-  "   FP9: ", "  FP10: ", "  FP11: ",
-  "  FP12: ", "  FP13: ", "  FP14: ",
-  "  FP15: ", "  FP16: ", "  FP17: ",
-  "  FP18: ", "  FP19: ", "  FP20: ",
-  "  FP21: ", "  FP22: ", "  FP23: ",
-  "  FP24: ", "  FP25: ", "  FP26: ",
-  "  FP27: ", "  FP28: ", "  FP29: ",
-  "  FP30: ", "  FPCR: ",
-
-  "   TA0: ", "   TA1: ", "   TA2: "
-};
-
-#define O(FIELD, LF)  offsetof(struct sigcontext, FIELD) + LF
-
-static const int offsets[NREGS] =
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
 {
-  O(sc_regs[0], 0),  O(sc_regs[1], 0),  O(sc_regs[2], 1),
-  O(sc_regs[3], 0),  O(sc_regs[4], 0),  O(sc_regs[5], 1),
-  O(sc_regs[6], 0),  O(sc_regs[7], 0),  O(sc_regs[8], 1),
-  O(sc_regs[9], 0),  O(sc_regs[10], 0), O(sc_regs[11], 1),
-  O(sc_regs[12], 0), O(sc_regs[13], 0), O(sc_regs[14], 1),
-  O(sc_regs[15], 0), O(sc_regs[16], 0), O(sc_regs[17], 1),
-  O(sc_regs[18], 0), O(sc_regs[19], 0), O(sc_regs[20], 1),
-  O(sc_regs[21], 0), O(sc_regs[22], 0), O(sc_regs[23], 1),
-  O(sc_regs[24], 0), O(sc_regs[25], 0), O(sc_regs[26], 1),
-  O(sc_regs[27], 0), O(sc_regs[28], 0), O(sc_regs[29], 1),
-  O(sc_regs[30], 0), O(sc_pc, 2),
-
-  O(sc_fpregs[0], 0),  O(sc_fpregs[1], 0),  O(sc_fpregs[2], 1),
-  O(sc_fpregs[3], 0),  O(sc_fpregs[4], 0),  O(sc_fpregs[5], 1),
-  O(sc_fpregs[6], 0),  O(sc_fpregs[7], 0),  O(sc_fpregs[8], 1),
-  O(sc_fpregs[9], 0),  O(sc_fpregs[10], 0), O(sc_fpregs[11], 1),
-  O(sc_fpregs[12], 0), O(sc_fpregs[13], 0), O(sc_fpregs[14], 1),
-  O(sc_fpregs[15], 0), O(sc_fpregs[16], 0), O(sc_fpregs[17], 1),
-  O(sc_fpregs[18], 0), O(sc_fpregs[19], 0), O(sc_fpregs[20], 1),
-  O(sc_fpregs[21], 0), O(sc_fpregs[22], 0), O(sc_fpregs[23], 1),
-  O(sc_fpregs[24], 0), O(sc_fpregs[25], 0), O(sc_fpregs[26], 1),
-  O(sc_fpregs[27], 0), O(sc_fpregs[28], 0), O(sc_fpregs[29], 1),
-  O(sc_fpregs[30], 0), O(sc_fpcr, 2),
-
-  O(sc_traparg_a0, 0),  O(sc_traparg_a1, 0),  O(sc_traparg_a2, 1)
-};
-
-#undef O
+  char *cp = _itoa_word (value, buf + len, 16, 0);
+  while (cp > buf)
+    *--cp = '0';
+}
 
 static void
-register_dump (int fd, struct sigcontext *ctx)
+register_dump (int fd, struct ucontext_t *ctx)
 {
-  char buf[NREGS*(8+16) + 25 + 80];
-  char *p = buf;
-  size_t i;
-
-  p = stpcpy (p, "Register dump:\n\n");
-
-  for (i = 0; i < NREGS; ++i)
-    {
-      int this_offset, this_lf;
-      unsigned long val;
-      signed long j;
-
-      this_offset = offsets[i];
-      this_lf = this_offset & 7;
-
-      val = *(unsigned long *)(((size_t)ctx + this_offset) & -8);
-
-      memcpy (p, regnames[i], 8);
-      p += 8;
-
-      for (j = 60; j >= 0; j -= 4)
-	{
-	  unsigned long x = (val >> j) & 15;
-	  x += x < 10 ? '0' : 'a' - 10;
-	  *p++ = x;
-	}
-
-      if (this_lf > 0)
-	{
-	  if (this_lf > 1)
-	    *p++ = '\n';
-	  *p++ = '\n';
-	}
-    }
-
-  write (fd, buf, p - buf);
+  struct iovec iov[31 * 2 + 2    /* REGS + PC.  */
+                   + 31 * 2 + 2  /* FREGS + FPCR.  */
+                   + (3 * 2)     /* TA0, TA1, TA3.  */
+                   + 1           /* '\n'.  */];
+  size_t nr = 0;
+
+#define ADD_STRING(str) \
+  iov[nr].iov_base = (char *) str;					      \
+  iov[nr].iov_len = strlen (str);					      \
+  ++nr
+#define ADD_MEM(str, len) \
+  iov[nr].iov_base = str;						      \
+  iov[nr].iov_len = len;						      \
+  ++nr
+
+  char regs[31][16];
+  char pc[16];
+  for (int i = 0; i < 31; i++)
+    hexvalue (ctx->uc_mcontext.sc_regs[i], regs[i], 16);
+  hexvalue (ctx->uc_mcontext.sc_pc, pc, 16);
+
+  /* Generate the output.  */
+  ADD_STRING ("Register dump:\n\n    V0: ");
+  ADD_MEM (regs[0], 16);
+  ADD_STRING ("    T0: ");
+  ADD_MEM (regs[1], 16);
+  ADD_STRING ("    T1: ");
+  ADD_MEM (regs[2], 16);
+  ADD_STRING ("\n    T2: ");
+  ADD_MEM (regs[3], 16);
+  ADD_STRING ("    T3: ");
+  ADD_MEM (regs[4], 16);
+  ADD_STRING ("    T4: ");
+  ADD_MEM (regs[5], 16);
+  ADD_STRING ("\n    T5: ");
+  ADD_MEM (regs[6], 16);
+  ADD_STRING ("    T6: ");
+  ADD_MEM (regs[7], 16);
+  ADD_STRING ("    T7: ");
+  ADD_MEM (regs[8], 16);
+  ADD_STRING ("\n    S0: ");
+  ADD_MEM (regs[9], 16);
+  ADD_STRING ("    S1: ");
+  ADD_MEM (regs[10], 16);
+  ADD_STRING ("    S2: ");
+  ADD_MEM (regs[11], 16);
+  ADD_STRING ("\n    S3: ");
+  ADD_MEM (regs[12], 16);
+  ADD_STRING ("    S4: ");
+  ADD_MEM (regs[13], 16);
+  ADD_STRING ("    S5: ");
+  ADD_MEM (regs[14], 16);
+  ADD_STRING ("\n    S6: ");
+  ADD_MEM (regs[15], 16);
+  ADD_STRING ("    A0: ");
+  ADD_MEM (regs[16], 16);
+  ADD_STRING ("    A1: ");
+  ADD_MEM (regs[17], 16);
+  ADD_STRING ("\n    A2: ");
+  ADD_MEM (regs[18], 16);
+  ADD_STRING ("    A3: ");
+  ADD_MEM (regs[19], 16);
+  ADD_STRING ("    A4: ");
+  ADD_MEM (regs[20], 16);
+  ADD_STRING ("\n    A5: ");
+  ADD_MEM (regs[21], 16);
+  ADD_STRING ("    T8: ");
+  ADD_MEM (regs[22], 16);
+  ADD_STRING ("    T9: ");
+  ADD_MEM (regs[23], 16);
+  ADD_STRING ("\n   T10: ");
+  ADD_MEM (regs[24], 16);
+  ADD_STRING ("   T11: ");
+  ADD_MEM (regs[25], 16);
+  ADD_STRING ("    RA: ");
+  ADD_MEM (regs[26], 16);
+  ADD_STRING ("\n   T12: ");
+  ADD_MEM (regs[27], 16);
+  ADD_STRING ("    AT: ");
+  ADD_MEM (regs[28], 16);
+  ADD_STRING ("    GP: ");
+  ADD_MEM (regs[29], 16);
+  ADD_STRING ("\n    SP: ");
+  ADD_MEM (regs[30], 16);
+  ADD_STRING ("    PC: ");
+  ADD_MEM (pc, 16);
+
+  char fpregs[31][16];
+  char fpcr[16];
+  for (int i = 0; i < 31; i++)
+    hexvalue (ctx->uc_mcontext.sc_fpregs[i], fpregs[i], 16);
+  hexvalue (ctx->uc_mcontext.sc_fpcr, fpcr, 16);
+
+  ADD_STRING ("\n\n   FP0: ");
+  ADD_MEM (fpregs[0], 16);
+  ADD_STRING ("   FP1: ");
+  ADD_MEM (fpregs[1], 16);
+  ADD_STRING ("   FP2: ");
+  ADD_MEM (fpregs[2], 16);
+  ADD_STRING ("\n   FP3: ");
+  ADD_MEM (fpregs[3], 16);
+  ADD_STRING ("   FP4: ");
+  ADD_MEM (fpregs[4], 16);
+  ADD_STRING ("   FP5: ");
+  ADD_MEM (fpregs[5], 16);
+  ADD_STRING ("\n   FP6: ");
+  ADD_MEM (fpregs[6], 16);
+  ADD_STRING ("   FP7: ");
+  ADD_MEM (fpregs[7], 16);
+  ADD_STRING ("   FP8: ");
+  ADD_MEM (fpregs[8], 16);
+  ADD_STRING ("\n   FP9: ");
+  ADD_MEM (fpregs[9], 16);
+  ADD_STRING ("  FP10: ");
+  ADD_MEM (fpregs[10], 16);
+  ADD_STRING ("  FP11: ");
+  ADD_MEM (fpregs[11], 16);
+  ADD_STRING ("\n  FP12: ");
+  ADD_MEM (fpregs[12], 16);
+  ADD_STRING ("  FP13: ");
+  ADD_MEM (fpregs[13], 16);
+  ADD_STRING ("  FP14: ");
+  ADD_MEM (fpregs[14], 16);
+  ADD_STRING ("\n  FP15: ");
+  ADD_MEM (fpregs[15], 16);
+  ADD_STRING ("  FP16: ");
+  ADD_MEM (fpregs[16], 16);
+  ADD_STRING ("  FP17: ");
+  ADD_MEM (fpregs[17], 16);
+  ADD_STRING ("\n  FP18: ");
+  ADD_MEM (fpregs[18], 16);
+  ADD_STRING ("  FP19: ");
+  ADD_MEM (fpregs[19], 16);
+  ADD_STRING ("  FP20: ");
+  ADD_MEM (fpregs[20], 16);
+  ADD_STRING ("\n  FP21: ");
+  ADD_MEM (fpregs[21], 16);
+  ADD_STRING ("  FP22: ");
+  ADD_MEM (fpregs[22], 16);
+  ADD_STRING ("  FP23: ");
+  ADD_MEM (fpregs[23], 16);
+  ADD_STRING ("\n  FP24: ");
+  ADD_MEM (fpregs[24], 16);
+  ADD_STRING ("  FP25: ");
+  ADD_MEM (fpregs[25], 16);
+  ADD_STRING ("  FP26: ");
+  ADD_MEM (fpregs[26], 16);
+  ADD_STRING ("\n  FP27: ");
+  ADD_MEM (fpregs[27], 16);
+  ADD_STRING ("  FP28: ");
+  ADD_MEM (fpregs[28], 16);
+  ADD_STRING ("  FP29: ");
+  ADD_MEM (fpregs[29], 16);
+  ADD_STRING ("\n  FP30: ");
+  ADD_MEM (fpregs[30], 16);
+  ADD_STRING ("  FPCR: ");
+  ADD_MEM (fpcr, 16);
+
+  char traparg[3][16];
+  hexvalue (ctx->uc_mcontext.sc_traparg_a0, traparg[0], 16);
+  hexvalue (ctx->uc_mcontext.sc_traparg_a1, traparg[1], 16);
+  hexvalue (ctx->uc_mcontext.sc_traparg_a2, traparg[2], 16);
+  ADD_STRING ("\n\n   TA0: ");
+  ADD_MEM (traparg[0], 16);
+  ADD_STRING ("   TA1: ");
+  ADD_MEM (traparg[1], 16);
+  ADD_STRING ("   TA2: ");
+  ADD_MEM (traparg[2], 16);
+
+  ADD_STRING ("\n");
+
+  /* Write the stuff out.  */
+  writev (fd, iov, nr);
 }
 
 #define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
index 45d06f9a12..2a2b71077d 100644
--- a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
@@ -15,5 +15,7 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT int _code, struct sigcontext *
-#define GET_PC(ctx)	((void *) (ctx)->sc_pc)
+#include <stdint.h>
+#include <sys/ucontext.h>
+
+#define GET_PC(ctx) ((uintptr_t)(((ucontext_t *) (ctx))->uc_mcontext.sc_pc))
diff --git a/sysdeps/unix/sysv/linux/arm/profil-counter.h b/sysdeps/unix/sysv/linux/arm/profil-counter.h
index 494c2172b6..db2eebeaa6 100644
--- a/sysdeps/unix/sysv/linux/arm/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/arm/profil-counter.h
@@ -16,19 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <signal.h>
-#include <sigcontextinfo.h>
-
-void
-__profil_counter (int signo, const SIGCONTEXT scp)
-{
-  profil_count ((void *) GET_PC (scp));
-
-  /* This is a hack to prevent the compiler from implementing the
-     above function call as a sibcall.  The sibcall would overwrite
-     the signal context.  */
-  asm volatile ("");
-}
+#include <sysdeps/unix/sysv/linux/profil-counter.h>
 #ifndef __profil_counter
 weak_alias (__profil_counter, profil_counter)
 #endif
diff --git a/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h b/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h
index 0bf3beaa0f..51fa921a54 100644
--- a/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h
@@ -16,24 +16,4 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sys/ucontext.h>
-
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-
-/* The sigcontext structure changed between 2.0 and 2.1 kernels.  On any
-   modern system we should be able to assume that the "new" format will be
-   in use.  */
-
-#define GET_PC(ctx)	((void *) (ctx)->uc_mcontext.arm_pc)
-
-/* There is no reliable way to get the sigcontext unless we use a
-   three-argument signal handler.  */
-#define __sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (__sigaction) (sig, act, oact); \
-})
-
-#define sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (sigaction) (sig, act, oact); \
-})
+#define GET_PC(ctx) ((uintptr_t)(((ucontext_t *) (ctx))->uc_mcontext.arm_pc))
diff --git a/sysdeps/unix/sysv/linux/csky/profil-counter.h b/sysdeps/unix/sysv/linux/csky/profil-counter.h
deleted file mode 100644
index b3e4279146..0000000000
--- a/sysdeps/unix/sysv/linux/csky/profil-counter.h
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* Low-level statistical profiling support function.  Linux/C-SKY version.
-   Copyright (C) 2018-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <signal.h>
-#include <sigcontextinfo.h>
-
-void
-__profil_counter (int signo, const SIGCONTEXT scp)
-{
-  profil_count ((void *) GET_PC (scp));
-
-  /* This is a hack to prevent the compiler from implementing the
-     above function call as a sibcall.  The sibcall would overwrite
-     the signal context.  */
-  asm volatile ("");
-}
diff --git a/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
index 4c1275402b..db2220e5b7 100644
--- a/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
@@ -16,17 +16,5 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT siginfo_t *_si, struct ucontext_t *
-#define GET_PC(ctx)     ((void *) (ctx)->uc_mcontext.__gregs.__pc)
-
-/* There is no reliable way to get the sigcontext unless we use a
-   three-argument signal handler.  */
-#define __sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (__sigaction) (sig, act, oact); \
-})
-
-#define sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (sigaction) (sig, act, oact); \
-})
+#define GET_PC(ctx) ((intptr_t) (((ucontext_t *) \
+		     (ctx))->uc_mcontext.__gregs.__pc))
diff --git a/sysdeps/unix/sysv/linux/hppa/profil-counter.h b/sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h
similarity index 77%
rename from sysdeps/unix/sysv/linux/hppa/profil-counter.h
rename to sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h
index bea7611465..b94f371566 100644
--- a/sysdeps/unix/sysv/linux/hppa/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h
@@ -1,5 +1,5 @@ 
 /* Machine-dependent SIGPROF signal handler.  PA-RISC version
-   Copyright (C) 1996-2019 Free Software Foundation, Inc.
+   Copyright (C) 2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -16,9 +16,7 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-static void
-__profil_counter (int signr, siginfo_t *si, ucontext_t *uctx)
-{
-  unsigned long ip = uctx->uc_mcontext.sc_iaoq[0] & ~0x3;
-  profil_count ((void *) ip);
-}
+#include <sys/ucontext.h>
+
+#define GET_PC(ctx) ((uintptr_t)(((ucontext_t *) \
+				 (ctx))->uc_mcontext.sc_iaoq[0] & ~0x3))
diff --git a/sysdeps/unix/sysv/linux/i386/profil-counter.h b/sysdeps/unix/sysv/linux/i386/profil-counter.h
deleted file mode 100644
index d6bbc04be8..0000000000
--- a/sysdeps/unix/sysv/linux/i386/profil-counter.h
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* Low-level statistical profiling support function.  Linux/i386 version.
-   Copyright (C) 1996-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <signal.h>
-#include <sigcontextinfo.h>
-
-static void
-__profil_counter (int signo, const SIGCONTEXT scp)
-{
-  profil_count ((void *) GET_PC (scp));
-
-  /* This is a hack to prevent the compiler from implementing the
-     above function call as a sibcall.  The sibcall would overwrite
-     the signal context.  */
-  asm volatile ("");
-}
diff --git a/sysdeps/unix/sysv/linux/i386/register-dump.h b/sysdeps/unix/sysv/linux/i386/register-dump.h
index 744e136ce7..8364238635 100644
--- a/sysdeps/unix/sysv/linux/i386/register-dump.h
+++ b/sysdeps/unix/sysv/linux/i386/register-dump.h
@@ -51,7 +51,7 @@  hexvalue (unsigned long int value, char *buf, size_t len)
 }
 
 static void
-register_dump (int fd, struct sigcontext *ctx)
+register_dump (int fd, struct ucontext_t *ctx)
 {
   char regs[21][8];
   char fpregs[31][8];
@@ -68,27 +68,27 @@  register_dump (int fd, struct sigcontext *ctx)
   ++nr
 
   /* Generate strings of register contents.  */
-  hexvalue (ctx->eax, regs[0], 8);
-  hexvalue (ctx->ebx, regs[1], 8);
-  hexvalue (ctx->ecx, regs[2], 8);
-  hexvalue (ctx->edx, regs[3], 8);
-  hexvalue (ctx->esi, regs[4], 8);
-  hexvalue (ctx->edi, regs[5], 8);
-  hexvalue (ctx->ebp, regs[6], 8);
-  hexvalue (ctx->esp, regs[7], 8);
-  hexvalue (ctx->eip, regs[8], 8);
-  hexvalue (ctx->eflags, regs[9], 8);
-  hexvalue (ctx->cs, regs[10], 4);
-  hexvalue (ctx->ds, regs[11], 4);
-  hexvalue (ctx->es, regs[12], 4);
-  hexvalue (ctx->fs, regs[13], 4);
-  hexvalue (ctx->gs, regs[14], 4);
-  hexvalue (ctx->ss, regs[15], 4);
-  hexvalue (ctx->trapno, regs[16], 8);
-  hexvalue (ctx->err, regs[17], 8);
-  hexvalue (ctx->oldmask, regs[18], 8);
-  hexvalue (ctx->esp_at_signal, regs[19], 8);
-  hexvalue (ctx->cr2, regs[20], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_EAX], regs[0], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_EBX], regs[1], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_ECX], regs[2], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_EDX], regs[3], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_ESI], regs[4], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_EDI], regs[5], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_EBP], regs[6], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_ESP], regs[7], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_EIP], regs[8], 8);
+  hexvalue (ctx->uc_flags, regs[9], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_CS], regs[10], 4);
+  hexvalue (ctx->uc_mcontext.gregs[REG_DS], regs[11], 4);
+  hexvalue (ctx->uc_mcontext.gregs[REG_ES], regs[12], 4);
+  hexvalue (ctx->uc_mcontext.gregs[REG_FS], regs[13], 4);
+  hexvalue (ctx->uc_mcontext.gregs[REG_GS], regs[14], 4);
+  hexvalue (ctx->uc_mcontext.gregs[REG_SS], regs[15], 4);
+  hexvalue (ctx->uc_mcontext.gregs[REG_TRAPNO], regs[16], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_ERR], regs[17], 8);
+  hexvalue (ctx->uc_mcontext.oldmask, regs[18], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_UESP], regs[19], 8);
+  hexvalue (ctx->uc_mcontext.cr2, regs[20], 8);
 
   /* Generate the output.  */
   ADD_STRING ("Register dump:\n\n EAX: ");
@@ -134,116 +134,112 @@  register_dump (int fd, struct sigcontext *ctx)
   ADD_STRING ("   CR2: ");
   ADD_MEM (regs[20], 8);
 
-  if (ctx->fpstate != NULL)
-    {
-
-      /* Generate output for the FPU control/status registers.  */
-      hexvalue (ctx->fpstate->cw, fpregs[0], 8);
-      hexvalue (ctx->fpstate->sw, fpregs[1], 8);
-      hexvalue (ctx->fpstate->tag, fpregs[2], 8);
-      hexvalue (ctx->fpstate->ipoff, fpregs[3], 8);
-      hexvalue (ctx->fpstate->cssel, fpregs[4], 4);
-      hexvalue (ctx->fpstate->dataoff, fpregs[5], 8);
-      hexvalue (ctx->fpstate->datasel, fpregs[6], 4);
-
-      ADD_STRING ("\n\n FPUCW: ");
-      ADD_MEM (fpregs[0], 8);
-      ADD_STRING ("   FPUSW: ");
-      ADD_MEM (fpregs[1], 8);
-      ADD_STRING ("   TAG: ");
-      ADD_MEM (fpregs[2], 8);
-      ADD_STRING ("\n IPOFF: ");
-      ADD_MEM (fpregs[3], 8);
-      ADD_STRING ("   CSSEL: ");
-      ADD_MEM (fpregs[4], 4);
-      ADD_STRING ("   DATAOFF: ");
-      ADD_MEM (fpregs[5], 8);
-      ADD_STRING ("   DATASEL: ");
-      ADD_MEM (fpregs[6], 4);
-
-      /* Now the real FPU registers.  */
-      hexvalue (ctx->fpstate->_st[0].exponent, fpregs[7], 8);
-      hexvalue (ctx->fpstate->_st[0].significand[3] << 16
-		| ctx->fpstate->_st[0].significand[2], fpregs[8], 8);
-      hexvalue (ctx->fpstate->_st[0].significand[1] << 16
-		| ctx->fpstate->_st[0].significand[0], fpregs[9], 8);
-      hexvalue (ctx->fpstate->_st[1].exponent, fpregs[10], 8);
-      hexvalue (ctx->fpstate->_st[1].significand[3] << 16
-		| ctx->fpstate->_st[1].significand[2], fpregs[11], 8);
-      hexvalue (ctx->fpstate->_st[1].significand[1] << 16
-		| ctx->fpstate->_st[1].significand[0], fpregs[12], 8);
-      hexvalue (ctx->fpstate->_st[2].exponent, fpregs[13], 8);
-      hexvalue (ctx->fpstate->_st[2].significand[3] << 16
-		| ctx->fpstate->_st[2].significand[2], fpregs[14], 8);
-      hexvalue (ctx->fpstate->_st[2].significand[1] << 16
-		| ctx->fpstate->_st[2].significand[0], fpregs[15], 8);
-      hexvalue (ctx->fpstate->_st[3].exponent, fpregs[16], 8);
-      hexvalue (ctx->fpstate->_st[3].significand[3] << 16
-		| ctx->fpstate->_st[3].significand[2], fpregs[17], 8);
-      hexvalue (ctx->fpstate->_st[3].significand[1] << 16
-		| ctx->fpstate->_st[3].significand[0], fpregs[18], 8);
-      hexvalue (ctx->fpstate->_st[4].exponent, fpregs[19], 8);
-      hexvalue (ctx->fpstate->_st[4].significand[3] << 16
-		| ctx->fpstate->_st[4].significand[2], fpregs[20], 8);
-      hexvalue (ctx->fpstate->_st[4].significand[1] << 16
-		| ctx->fpstate->_st[4].significand[0], fpregs[21], 8);
-      hexvalue (ctx->fpstate->_st[5].exponent, fpregs[22], 8);
-      hexvalue (ctx->fpstate->_st[5].significand[3] << 16
-		| ctx->fpstate->_st[5].significand[2], fpregs[23], 8);
-      hexvalue (ctx->fpstate->_st[5].significand[1] << 16
-		| ctx->fpstate->_st[5].significand[0], fpregs[24], 8);
-      hexvalue (ctx->fpstate->_st[6].exponent, fpregs[25], 8);
-      hexvalue (ctx->fpstate->_st[6].significand[3] << 16
-		| ctx->fpstate->_st[6].significand[2], fpregs[26], 8);
-      hexvalue (ctx->fpstate->_st[6].significand[1] << 16
-		| ctx->fpstate->_st[6].significand[0], fpregs[27], 8);
-      hexvalue (ctx->fpstate->_st[7].exponent, fpregs[28], 8);
-      hexvalue (ctx->fpstate->_st[7].significand[3] << 16
-		| ctx->fpstate->_st[7].significand[2], fpregs[29], 8);
-      hexvalue (ctx->fpstate->_st[7].significand[1] << 16
-		| ctx->fpstate->_st[7].significand[0], fpregs[30], 8);
-
-      ADD_STRING ("\n\n ST(0) ");
-      ADD_MEM (fpregs[7], 4);
-      ADD_STRING (" ");
-      ADD_MEM (fpregs[8], 8);
-      ADD_MEM (fpregs[9], 8);
-      ADD_STRING ("   ST(1) ");
-      ADD_MEM (fpregs[10], 4);
-      ADD_STRING (" ");
-      ADD_MEM (fpregs[11], 8);
-      ADD_MEM (fpregs[12], 8);
-      ADD_STRING ("\n ST(2) ");
-      ADD_MEM (fpregs[13], 4);
-      ADD_STRING (" ");
-      ADD_MEM (fpregs[14], 8);
-      ADD_MEM (fpregs[15], 8);
-      ADD_STRING ("   ST(3) ");
-      ADD_MEM (fpregs[16], 4);
-      ADD_STRING (" ");
-      ADD_MEM (fpregs[17], 8);
-      ADD_MEM (fpregs[18], 8);
-      ADD_STRING ("\n ST(4) ");
-      ADD_MEM (fpregs[19], 4);
-      ADD_STRING (" ");
-      ADD_MEM (fpregs[20], 8);
-      ADD_MEM (fpregs[21], 8);
-      ADD_STRING ("   ST(5) ");
-      ADD_MEM (fpregs[22], 4);
-      ADD_STRING (" ");
-      ADD_MEM (fpregs[23], 8);
-      ADD_MEM (fpregs[24], 8);
-      ADD_STRING ("\n ST(6) ");
-      ADD_MEM (fpregs[25], 4);
-      ADD_STRING (" ");
-      ADD_MEM (fpregs[26], 8);
-      ADD_MEM (fpregs[27], 8);
-      ADD_STRING ("   ST(7) ");
-      ADD_MEM (fpregs[28], 4);
-      ADD_STRING (" ");
-      ADD_MEM (fpregs[29], 8);
-      ADD_MEM (fpregs[30], 8);
-    }
+  /* Generate output for the FPU control/status registers.  */
+  hexvalue (ctx->__fpregs_mem.cw, fpregs[0], 8);
+  hexvalue (ctx->__fpregs_mem.sw, fpregs[1], 8);
+  hexvalue (ctx->__fpregs_mem.tag, fpregs[2], 8);
+  hexvalue (ctx->__fpregs_mem.ipoff, fpregs[3], 8);
+  hexvalue (ctx->__fpregs_mem.cssel, fpregs[4], 4);
+  hexvalue (ctx->__fpregs_mem.dataoff, fpregs[5], 8);
+  hexvalue (ctx->__fpregs_mem.datasel, fpregs[6], 4);
+
+  ADD_STRING ("\n\n FPUCW: ");
+  ADD_MEM (fpregs[0], 8);
+  ADD_STRING ("   FPUSW: ");
+  ADD_MEM (fpregs[1], 8);
+  ADD_STRING ("   TAG: ");
+  ADD_MEM (fpregs[2], 8);
+  ADD_STRING ("\n IPOFF: ");
+  ADD_MEM (fpregs[3], 8);
+  ADD_STRING ("   CSSEL: ");
+  ADD_MEM (fpregs[4], 4);
+  ADD_STRING ("   DATAOFF: ");
+  ADD_MEM (fpregs[5], 8);
+  ADD_STRING ("   DATASEL: ");
+  ADD_MEM (fpregs[6], 4);
+
+  /* Now the real FPU registers.  */
+  hexvalue (ctx->__fpregs_mem._st[0].exponent, fpregs[7], 8);
+  hexvalue (ctx->__fpregs_mem._st[0].significand[3] << 16
+		| ctx->__fpregs_mem._st[0].significand[2], fpregs[8], 8);
+  hexvalue (ctx->__fpregs_mem._st[0].significand[1] << 16
+		| ctx->__fpregs_mem._st[0].significand[0], fpregs[9], 8);
+  hexvalue (ctx->__fpregs_mem._st[1].exponent, fpregs[10], 8);
+  hexvalue (ctx->__fpregs_mem._st[1].significand[3] << 16
+		| ctx->__fpregs_mem._st[1].significand[2], fpregs[11], 8);
+  hexvalue (ctx->__fpregs_mem._st[1].significand[1] << 16
+		| ctx->__fpregs_mem._st[1].significand[0], fpregs[12], 8);
+  hexvalue (ctx->__fpregs_mem._st[2].exponent, fpregs[13], 8);
+  hexvalue (ctx->__fpregs_mem._st[2].significand[3] << 16
+		| ctx->__fpregs_mem._st[2].significand[2], fpregs[14], 8);
+  hexvalue (ctx->__fpregs_mem._st[2].significand[1] << 16
+		| ctx->__fpregs_mem._st[2].significand[0], fpregs[15], 8);
+  hexvalue (ctx->__fpregs_mem._st[3].exponent, fpregs[16], 8);
+  hexvalue (ctx->__fpregs_mem._st[3].significand[3] << 16
+		| ctx->__fpregs_mem._st[3].significand[2], fpregs[17], 8);
+  hexvalue (ctx->__fpregs_mem._st[3].significand[1] << 16
+		| ctx->__fpregs_mem._st[3].significand[0], fpregs[18], 8);
+  hexvalue (ctx->__fpregs_mem._st[4].exponent, fpregs[19], 8);
+  hexvalue (ctx->__fpregs_mem._st[4].significand[3] << 16
+		| ctx->__fpregs_mem._st[4].significand[2], fpregs[20], 8);
+  hexvalue (ctx->__fpregs_mem._st[4].significand[1] << 16
+		| ctx->__fpregs_mem._st[4].significand[0], fpregs[21], 8);
+  hexvalue (ctx->__fpregs_mem._st[5].exponent, fpregs[22], 8);
+  hexvalue (ctx->__fpregs_mem._st[5].significand[3] << 16
+		| ctx->__fpregs_mem._st[5].significand[2], fpregs[23], 8);
+  hexvalue (ctx->__fpregs_mem._st[5].significand[1] << 16
+		| ctx->__fpregs_mem._st[5].significand[0], fpregs[24], 8);
+  hexvalue (ctx->__fpregs_mem._st[6].exponent, fpregs[25], 8);
+  hexvalue (ctx->__fpregs_mem._st[6].significand[3] << 16
+		| ctx->__fpregs_mem._st[6].significand[2], fpregs[26], 8);
+  hexvalue (ctx->__fpregs_mem._st[6].significand[1] << 16
+		| ctx->__fpregs_mem._st[6].significand[0], fpregs[27], 8);
+  hexvalue (ctx->__fpregs_mem._st[7].exponent, fpregs[28], 8);
+  hexvalue (ctx->__fpregs_mem._st[7].significand[3] << 16
+		| ctx->__fpregs_mem._st[7].significand[2], fpregs[29], 8);
+  hexvalue (ctx->__fpregs_mem._st[7].significand[1] << 16
+		| ctx->__fpregs_mem._st[7].significand[0], fpregs[30], 8);
+
+  ADD_STRING ("\n\n ST(0) ");
+  ADD_MEM (fpregs[7], 4);
+  ADD_STRING (" ");
+  ADD_MEM (fpregs[8], 8);
+  ADD_MEM (fpregs[9], 8);
+  ADD_STRING ("   ST(1) ");
+  ADD_MEM (fpregs[10], 4);
+  ADD_STRING (" ");
+  ADD_MEM (fpregs[11], 8);
+  ADD_MEM (fpregs[12], 8);
+  ADD_STRING ("\n ST(2) ");
+  ADD_MEM (fpregs[13], 4);
+  ADD_STRING (" ");
+  ADD_MEM (fpregs[14], 8);
+  ADD_MEM (fpregs[15], 8);
+  ADD_STRING ("   ST(3) ");
+  ADD_MEM (fpregs[16], 4);
+  ADD_STRING (" ");
+  ADD_MEM (fpregs[17], 8);
+  ADD_MEM (fpregs[18], 8);
+  ADD_STRING ("\n ST(4) ");
+  ADD_MEM (fpregs[19], 4);
+  ADD_STRING (" ");
+  ADD_MEM (fpregs[20], 8);
+  ADD_MEM (fpregs[21], 8);
+  ADD_STRING ("   ST(5) ");
+  ADD_MEM (fpregs[22], 4);
+  ADD_STRING (" ");
+  ADD_MEM (fpregs[23], 8);
+  ADD_MEM (fpregs[24], 8);
+  ADD_STRING ("\n ST(6) ");
+  ADD_MEM (fpregs[25], 4);
+  ADD_STRING (" ");
+  ADD_MEM (fpregs[26], 8);
+  ADD_MEM (fpregs[27], 8);
+  ADD_STRING ("   ST(7) ");
+  ADD_MEM (fpregs[28], 4);
+  ADD_STRING (" ");
+  ADD_MEM (fpregs[29], 8);
+  ADD_MEM (fpregs[30], 8);
 
   ADD_STRING ("\n");
 
@@ -252,4 +248,4 @@  register_dump (int fd, struct sigcontext *ctx)
 }
 
 
-#define REGISTER_DUMP register_dump (fd, &ctx)
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h b/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
index 789a127a58..19533b71c8 100644
--- a/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
@@ -16,5 +16,5 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT struct sigcontext
-#define GET_PC(ctx)	((void *) ctx.eip)
+#define GET_PC(ctx) ((uintptr_t)(((ucontext_t *) \
+				 (ctx))->uc_mcontext.gregs[REG_EIP]))
diff --git a/sysdeps/unix/sysv/linux/ia64/profil-counter.h b/sysdeps/unix/sysv/linux/ia64/profil-counter.h
deleted file mode 100644
index cafe0903c8..0000000000
--- a/sysdeps/unix/sysv/linux/ia64/profil-counter.h
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* Machine-dependent SIGPROF signal handler.  IA-64 version.
-   Copyright (C) 1996-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-/* In many Unix systems signal handlers are called like this
-   and the interrupted PC is easily findable in the `struct sigcontext'.  */
-
-static void
-__profil_counter (int signr, siginfo_t *si, struct sigcontext *scp)
-{
-  unsigned long ip = scp->sc_ip & ~0X3ULL, slot = scp->sc_ip & 0x3ull;
-
-  /* Note: Linux/ia64 encodes the slot number in bits 0 and 1.  We
-     want to multiply the slot number by four so we can use bins of
-     width 4 to get accurate instruction-level profiling.  */
-  profil_count ((void *) (ip + 4*slot));
-}
diff --git a/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
index 06711a5eee..cee70e30e6 100644
--- a/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
@@ -15,5 +15,10 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT siginfo_t *_si, struct sigcontext *
-#define GET_PC(ctx)	((ctx)->sc_ip)
+/* Different that other architectures, ia64 pass a sigcontext_t struct
+   in third argument for sa_sigaction handler with SA_SIGINFO.  */
+#define GET_PC(ctx) \
+  ({ uintptr_t __sc_ip = ((struct sigcontext *) (ctx))->sc_ip;		\
+     uintptr_t __pc = (__sc_ip & ~0x3ULL) + (4 * (__sc_ip & 0x3ull));	\
+     __pc;								\
+  })
diff --git a/sysdeps/unix/sysv/linux/m68k/register-dump.h b/sysdeps/unix/sysv/linux/m68k/register-dump.h
index b9941e813e..69f8e4c3f0 100644
--- a/sysdeps/unix/sysv/linux/m68k/register-dump.h
+++ b/sysdeps/unix/sysv/linux/m68k/register-dump.h
@@ -39,35 +39,9 @@ 
 
 */
 
-/* Linux saves only the call-clobbered registers in the sigcontext.  We
-   need to use a trampoline that saves the rest so that the C code can
-   access them.  We use the sc_fpstate field, since the handler is not
-   supposed to return anyway, thus it doesn't matter that it's clobbered.  */
-
-/* static */ void catch_segfault (int, int, struct sigcontext *);
-
-/* Dummy function so that we can use asm with arguments.  */
-static void __attribute_used__
-__dummy__ (void)
-{
-  asm ("\n\
-catch_segfault:\n\
-	move.l 12(%%sp),%%a0\n\
-	lea %c0(%%a0),%%a0\n\
-	/* Clear the first 4 bytes to make it a null fp state, just\n\
-	   in case the handler does return.  */\n\
-	clr.l (%%a0)+\n\
-	movem.l %%d2-%%d7/%%a2-%%a6,(%%a0)\n"
-#ifndef __mcoldfire__
-       "fmovem.x %%fp2-%%fp7,11*4(%%a0)\n"
-#elif defined __mcffpu__
-       "fmovem.d %%fp2-%%fp7,11*4(%%a0)\n"
-#endif
-       "jra real_catch_segfault"
-       : : "n" (offsetof (struct sigcontext, sc_fpstate)));
-}
-#define catch_segfault(a,b) \
-  __attribute_used__ real_catch_segfault(a,b)
+#define FPCONTEXT_SIZE  216
+#define uc_formatvec    __glibc_reserved1[FPCONTEXT_SIZE/4]
+#define uc_oldmask      uc_sigmask.__val[0]
 
 static void
 hexvalue (unsigned long int value, char *buf, size_t len)
@@ -78,13 +52,38 @@  hexvalue (unsigned long int value, char *buf, size_t len)
 }
 
 static void
-register_dump (int fd, struct sigcontext *ctx)
+register_dump (int fd, struct ucontext_t *ctx)
 {
+  /* Linux does not save the FP state in case of emulated floating point.  */
+#ifndef __mcoldfire__
+  __asm__ volatile (".chip 68k/68881\n\t"
+                    "fmovem.x %%fp0-%%fp7, %0\n\t"
+                    "fmovem.l %%fpcr, %1\n\t"
+                    "fmovem.l %%fpsr, %2\n\t"
+                    "fmovem.l %%fpiar, %3\n\t"
+                    ".chip 68k"
+                    : "=m" (*ctx->uc_mcontext.fpregs.f_fpregs),
+                      "=m" (ctx->uc_mcontext.fpregs.f_pcr),
+                      "=m" (ctx->uc_mcontext.fpregs.f_pcr),
+                      "=m" (ctx->uc_mcontext.fpregs.f_pcr)
+                    : /* no inputs.  */
+                    : "memory");
+#elif defined __mcffpu__
+  __asm__ volatile ("fmovemd %%fp0-%%fp7, %0\n\t"
+                    "fmovel  %%fpcr, %1\n\t"
+                    "fmovel  %%fpsr, %2\n\t"
+                    "fmovel  %%fpiar, %3\n\t"
+                    : "=m" (*ctx->uc_mcontext.fpregs.f_fpregs),
+                      "=m" (ctx->uc_mcontext.fpregs.f_pcr),
+                      "=m" (ctx->uc_mcontext.fpregs.f_pcr),
+                      "=m" (ctx->uc_mcontext.fpregs.f_pcr)
+                    : /* no inputs.  */
+                    : "memory");
+#endif
+  
   char regs[20][8];
   char fpregs[11][24];
   struct iovec iov[63], *next_iov = iov;
-  unsigned long *p = (unsigned long *) ctx->sc_fpstate + 1;
-  unsigned long *pfp = (unsigned long *) ctx->sc_fpregs;
   int i, j, fpreg_size;
 
 #define ADD_STRING(str) \
@@ -103,35 +102,33 @@  register_dump (int fd, struct sigcontext *ctx)
 #endif
 
   /* Generate strings of register contents.  */
-  hexvalue (ctx->sc_d0, regs[0], 8);
-  hexvalue (ctx->sc_d1, regs[1], 8);
-  hexvalue (*p++, regs[2], 8);
-  hexvalue (*p++, regs[3], 8);
-  hexvalue (*p++, regs[4], 8);
-  hexvalue (*p++, regs[5], 8);
-  hexvalue (*p++, regs[6], 8);
-  hexvalue (*p++, regs[7], 8);
-  hexvalue (ctx->sc_a0, regs[8], 8);
-  hexvalue (ctx->sc_a1, regs[9], 8);
-  hexvalue (*p++, regs[10], 8);
-  hexvalue (*p++, regs[11], 8);
-  hexvalue (*p++, regs[12], 8);
-  hexvalue (*p++, regs[13], 8);
-  hexvalue (*p++, regs[14], 8);
-  hexvalue (ctx->sc_usp, regs[15], 8);
-  hexvalue (ctx->sc_pc, regs[16], 8);
-  hexvalue (ctx->sc_sr, regs[17], 4);
-  hexvalue (ctx->sc_mask, regs[18], 8);
-  hexvalue (ctx->sc_formatvec & 0xfff, regs[19], 4);
-  for (i = 0; i < 2; i++)
-    for (j = 0; j < fpreg_size; j += 8)
-      hexvalue (*pfp++, fpregs[i] + j, 8);
-  for (i = 2; i < 8; i++)
+  hexvalue (ctx->uc_mcontext.gregs[R_D0], regs[0], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_D1], regs[1], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_D2], regs[2], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_D3], regs[3], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_D4], regs[4], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_D5], regs[5], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_D6], regs[6], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_D7], regs[7], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_A0], regs[8], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_A1], regs[9], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_A2], regs[10], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_A3], regs[11], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_A4], regs[12], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_A5], regs[13], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_A6], regs[14], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_SP], regs[15], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_PC], regs[16], 8);
+  hexvalue (ctx->uc_mcontext.gregs[R_PS], regs[17], 4);
+  hexvalue (ctx->uc_oldmask, regs[18], 8);
+  hexvalue (ctx->uc_formatvec & 0xfff, regs[19], 4);
+
+  for (i = 0; i < 8; i++)
     for (j = 0; j < fpreg_size; j += 8)
-      hexvalue (*p++, fpregs[i] + j, 8);
-  hexvalue (ctx->sc_fpcntl[0], fpregs[8], 8);
-  hexvalue (ctx->sc_fpcntl[1], fpregs[9], 8);
-  hexvalue (ctx->sc_fpcntl[2], fpregs[10], 8);
+      hexvalue (ctx->uc_mcontext.fpregs.f_fpregs[i][j/8], fpregs[i] + j, 8);
+  hexvalue (ctx->uc_mcontext.fpregs.f_pcr, fpregs[8], 8);
+  hexvalue (ctx->uc_mcontext.fpregs.f_psr, fpregs[9], 8);
+  hexvalue (ctx->uc_mcontext.fpregs.f_fpiaddr, fpregs[10], 8);
 
   /* Generate the output.  */
   ADD_STRING ("Register dump:\n\n  D0: ");
diff --git a/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h b/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h
index 27bfe6e747..7267ad3f0f 100644
--- a/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h
@@ -16,5 +16,5 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT int _code, struct sigcontext *
-#define GET_PC(ctx)	((void *) (ctx)->sc_pc)
+#define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) \
+				  (ctx))->uc_mcontext.gregs[R_PC]))
diff --git a/sysdeps/unix/sysv/linux/microblaze/profil-counter.h b/sysdeps/unix/sysv/linux/microblaze/profil-counter.h
deleted file mode 100644
index 8a6a0bcf3d..0000000000
--- a/sysdeps/unix/sysv/linux/microblaze/profil-counter.h
+++ /dev/null
@@ -1,2 +0,0 @@ 
-/* We can use the ix86 version.  */
-#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h b/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h
index f8d7b858ea..b9121bcf06 100644
--- a/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h
@@ -16,5 +16,5 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT int _code, ucontext_t *
-#define GET_PC(ctx)    ((void *) (ctx)->uc_mcontext.regs.pc)
+#define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) \
+				  (ctx))->uc_mcontext.regs.pc))
diff --git a/sysdeps/unix/sysv/linux/mips/profil-counter.h b/sysdeps/unix/sysv/linux/mips/profil-counter.h
deleted file mode 100644
index 8a6a0bcf3d..0000000000
--- a/sysdeps/unix/sysv/linux/mips/profil-counter.h
+++ /dev/null
@@ -1,2 +0,0 @@ 
-/* We can use the ix86 version.  */
-#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h b/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h
index a28d8b23c7..47b9277041 100644
--- a/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h
@@ -16,17 +16,4 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-
-#include <sgidefs.h>
-
-#if _MIPS_SIM == _ABIO32
-
-#define SIGCONTEXT unsigned long _code, struct sigcontext *
-#define GET_PC(ctx)	((void *) (unsigned long) ctx->sc_pc)
-
-#else
-
-#define SIGCONTEXT unsigned long _code, ucontext_t *
-#define GET_PC(ctx)	((void *) (unsigned long) ctx->uc_mcontext.pc)
-
-#endif
+#define GET_PC(ctx) ((uintptr_t) ((ucontext_t *) (ctx))->uc_mcontext.pc)
diff --git a/sysdeps/unix/sysv/linux/nios2/profil-counter.h b/sysdeps/unix/sysv/linux/nios2/profil-counter.h
deleted file mode 100644
index 8a6a0bcf3d..0000000000
--- a/sysdeps/unix/sysv/linux/nios2/profil-counter.h
+++ /dev/null
@@ -1,2 +0,0 @@ 
-/* We can use the ix86 version.  */
-#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h b/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h
index dbbb47b50d..95bbb9c537 100644
--- a/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h
@@ -16,20 +16,5 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sys/ucontext.h>
-#include "kernel-features.h"
-
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.regs[27])
-
-/* There is no reliable way to get the sigcontext unless we use a
-   three-argument signal handler.  */
-#define __sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (__sigaction) (sig, act, oact); \
-})
-
-#define sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (sigaction) (sig, act, oact); \
-})
+#define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) \
+				  (ctx))->uc_mcontext.regs[27]))
diff --git a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
deleted file mode 100644
index 8a6a0bcf3d..0000000000
--- a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
+++ /dev/null
@@ -1,2 +0,0 @@ 
-/* We can use the ix86 version.  */
-#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h b/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
index 0c31bdcfe0..565dd6ff6e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
@@ -17,5 +17,10 @@ 
 
 #include <signal.h>
 
-#define SIGCONTEXT struct sigcontext *
-#define GET_PC(ctx)	((void *)((ctx)->regs->nip))
+#ifdef __powerpc64__
+# define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) \
+			           (ctx))->uc_mcontext.gp_regs[PT_NIP]))
+#else
+# define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) \
+				   (ctx))->uc_mcontext.uc_regs->gregs[PT_NIP]))
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/profil-counter.h b/sysdeps/unix/sysv/linux/profil-counter.h
similarity index 67%
rename from sysdeps/unix/sysv/linux/x86_64/profil-counter.h
rename to sysdeps/unix/sysv/linux/profil-counter.h
index 48a266e3ef..c826344395 100644
--- a/sysdeps/unix/sysv/linux/x86_64/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/profil-counter.h
@@ -1,11 +1,11 @@ 
-/* Low-level statistical profiling support function.  Linux/x86-64 version.
+/* Low-level statistical profiling support function.  Linux version.
    Copyright (C) 2001-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
 
    The GNU C Library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,10 +19,11 @@ 
 #include <signal.h>
 #include <sigcontextinfo.h>
 
+/* sa_sigaction signature to use along SA_SIGINFO.  */
 static void
-__profil_counter (int signo, SIGCONTEXT scp)
+__profil_counter (int signo, siginfo_t *info, void *ctx)
 {
-  profil_count ((void *) GET_PC (scp));
+  profil_count (GET_PC (ctx));
 
   /* This is a hack to prevent the compiler from implementing the
      above function call as a sibcall.  The sibcall would overwrite
diff --git a/sysdeps/unix/sysv/linux/riscv/profil-counter.h b/sysdeps/unix/sysv/linux/riscv/profil-counter.h
deleted file mode 100644
index 8ed88f12a0..0000000000
--- a/sysdeps/unix/sysv/linux/riscv/profil-counter.h
+++ /dev/null
@@ -1,31 +0,0 @@ 
-/* Low-level statistical profiling support function.  Linux/RISC-V version.
-   Copyright (C) 1996-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <signal.h>
-#include <sigcontextinfo.h>
-
-static void
-__profil_counter (int signo, const SIGCONTEXT scp)
-{
-  profil_count ((void *) GET_PC (scp));
-
-  /* This is a hack to prevent the compiler from implementing the
-     above function call as a sibcall.  The sibcall would overwrite
-     the signal context.  */
-  asm volatile ("");
-}
diff --git a/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
index 27ed9bdb87..f56966ec52 100644
--- a/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
@@ -18,5 +18,5 @@ 
 
 #include <sys/ucontext.h>
 
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-#define GET_PC(ctx)	((void *) ctx->uc_mcontext.__gregs[REG_PC])
+#define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) \
+				  (ctx))->uc_mcontext.__gregs[REG_PC]))
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h b/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h
deleted file mode 100644
index 47ab8f38e0..0000000000
--- a/sysdeps/unix/sysv/linux/s390/s390-32/profil-counter.h
+++ /dev/null
@@ -1,26 +0,0 @@ 
-/* Low-level statistical profiling support function.  Linux/s390 version.
-   Copyright (C) 2000-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <signal.h>
-#include <sigcontextinfo.h>
-
-static void
-__profil_counter (int signo, SIGCONTEXT scp)
-{
-  profil_count((void *) ((unsigned long) GET_PC (scp) & 0x7fffffffUL));
-}
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h b/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h
index bd69e8dd7d..0ad389d538 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/register-dump.h
@@ -45,7 +45,7 @@  hexvalue (unsigned long int value, char *buf, size_t len)
 }
 
 static void
-register_dump (int fd, struct sigcontext *ctx)
+register_dump (int fd, struct ucontext_t *ctx)
 {
   char regs[19][8];
   struct iovec iov[40];
@@ -61,24 +61,24 @@  register_dump (int fd, struct sigcontext *ctx)
   ++nr
 
   /* Generate strings of register contents.  */
-  hexvalue (ctx->sregs->regs.gprs[0], regs[0], 8);
-  hexvalue (ctx->sregs->regs.gprs[1], regs[1], 8);
-  hexvalue (ctx->sregs->regs.gprs[2], regs[2], 8);
-  hexvalue (ctx->sregs->regs.gprs[3], regs[3], 8);
-  hexvalue (ctx->sregs->regs.gprs[4], regs[4], 8);
-  hexvalue (ctx->sregs->regs.gprs[5], regs[5], 8);
-  hexvalue (ctx->sregs->regs.gprs[6], regs[6], 8);
-  hexvalue (ctx->sregs->regs.gprs[7], regs[7], 8);
-  hexvalue (ctx->sregs->regs.gprs[8], regs[8], 8);
-  hexvalue (ctx->sregs->regs.gprs[9], regs[9], 8);
-  hexvalue (ctx->sregs->regs.gprs[10], regs[10], 8);
-  hexvalue (ctx->sregs->regs.gprs[11], regs[11], 8);
-  hexvalue (ctx->sregs->regs.gprs[12], regs[12], 8);
-  hexvalue (ctx->sregs->regs.gprs[13], regs[13], 8);
-  hexvalue (ctx->sregs->regs.gprs[14], regs[14], 8);
-  hexvalue (ctx->sregs->regs.gprs[15], regs[15], 8);
-  hexvalue (ctx->sregs->regs.psw.mask, regs[16], 8);
-  hexvalue (ctx->sregs->regs.psw.addr, regs[17], 8);
+  hexvalue (ctx->uc_mcontext.gregs[0], regs[0], 8);
+  hexvalue (ctx->uc_mcontext.gregs[1], regs[1], 8);
+  hexvalue (ctx->uc_mcontext.gregs[2], regs[2], 8);
+  hexvalue (ctx->uc_mcontext.gregs[3], regs[3], 8);
+  hexvalue (ctx->uc_mcontext.gregs[4], regs[4], 8);
+  hexvalue (ctx->uc_mcontext.gregs[5], regs[5], 8);
+  hexvalue (ctx->uc_mcontext.gregs[6], regs[6], 8);
+  hexvalue (ctx->uc_mcontext.gregs[7], regs[7], 8);
+  hexvalue (ctx->uc_mcontext.gregs[8], regs[8], 8);
+  hexvalue (ctx->uc_mcontext.gregs[9], regs[9], 8);
+  hexvalue (ctx->uc_mcontext.gregs[10], regs[10], 8);
+  hexvalue (ctx->uc_mcontext.gregs[11], regs[11], 8);
+  hexvalue (ctx->uc_mcontext.gregs[12], regs[12], 8);
+  hexvalue (ctx->uc_mcontext.gregs[13], regs[13], 8);
+  hexvalue (ctx->uc_mcontext.gregs[14], regs[14], 8);
+  hexvalue (ctx->uc_mcontext.gregs[15], regs[15], 8);
+  hexvalue (ctx->uc_mcontext.psw.mask, regs[16], 8);
+  hexvalue (ctx->uc_mcontext.psw.addr, regs[17], 8);
 
   /* Generate the output.  */
   ADD_STRING ("Register dump:\n\n GPR0: ");
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h b/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h
deleted file mode 100644
index 41301afe9c..0000000000
--- a/sysdeps/unix/sysv/linux/s390/s390-64/profil-counter.h
+++ /dev/null
@@ -1,26 +0,0 @@ 
-/* Low-level statistical profiling support function.  Linux/s390 version.
-   Copyright (C) 2000-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <signal.h>
-#include <sigcontextinfo.h>
-
-static void
-__profil_counter (int signo, SIGCONTEXT scp)
-{
-  profil_count ((void *) GET_PC (scp));
-}
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h b/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h
index f3af16b223..a00516746a 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/register-dump.h
@@ -48,7 +48,7 @@  hexvalue (unsigned long int value, char *buf, size_t len)
 }
 
 static void
-register_dump (int fd, struct sigcontext *ctx)
+register_dump (int fd, struct ucontext_t *ctx)
 {
   char regs[19][16];
   struct iovec iov[40];
@@ -64,24 +64,24 @@  register_dump (int fd, struct sigcontext *ctx)
   ++nr
 
   /* Generate strings of register contents.  */
-  hexvalue (ctx->sregs->regs.gprs[0], regs[0], 16);
-  hexvalue (ctx->sregs->regs.gprs[1], regs[1], 16);
-  hexvalue (ctx->sregs->regs.gprs[2], regs[2], 16);
-  hexvalue (ctx->sregs->regs.gprs[3], regs[3], 16);
-  hexvalue (ctx->sregs->regs.gprs[4], regs[4], 16);
-  hexvalue (ctx->sregs->regs.gprs[5], regs[5], 16);
-  hexvalue (ctx->sregs->regs.gprs[6], regs[6], 16);
-  hexvalue (ctx->sregs->regs.gprs[7], regs[7], 16);
-  hexvalue (ctx->sregs->regs.gprs[8], regs[8], 16);
-  hexvalue (ctx->sregs->regs.gprs[9], regs[9], 16);
-  hexvalue (ctx->sregs->regs.gprs[10], regs[10], 16);
-  hexvalue (ctx->sregs->regs.gprs[11], regs[11], 16);
-  hexvalue (ctx->sregs->regs.gprs[12], regs[12], 16);
-  hexvalue (ctx->sregs->regs.gprs[13], regs[13], 16);
-  hexvalue (ctx->sregs->regs.gprs[14], regs[14], 16);
-  hexvalue (ctx->sregs->regs.gprs[15], regs[15], 16);
-  hexvalue (ctx->sregs->regs.psw.mask, regs[16], 16);
-  hexvalue (ctx->sregs->regs.psw.addr, regs[17], 16);
+  hexvalue (ctx->uc_mcontext.gregs[0], regs[0], 16);
+  hexvalue (ctx->uc_mcontext.gregs[1], regs[1], 16);
+  hexvalue (ctx->uc_mcontext.gregs[2], regs[2], 16);
+  hexvalue (ctx->uc_mcontext.gregs[3], regs[3], 16);
+  hexvalue (ctx->uc_mcontext.gregs[4], regs[4], 16);
+  hexvalue (ctx->uc_mcontext.gregs[5], regs[5], 16);
+  hexvalue (ctx->uc_mcontext.gregs[6], regs[6], 16);
+  hexvalue (ctx->uc_mcontext.gregs[7], regs[7], 16);
+  hexvalue (ctx->uc_mcontext.gregs[8], regs[8], 16);
+  hexvalue (ctx->uc_mcontext.gregs[9], regs[9], 16);
+  hexvalue (ctx->uc_mcontext.gregs[10], regs[10], 16);
+  hexvalue (ctx->uc_mcontext.gregs[11], regs[11], 16);
+  hexvalue (ctx->uc_mcontext.gregs[12], regs[12], 16);
+  hexvalue (ctx->uc_mcontext.gregs[13], regs[13], 16);
+  hexvalue (ctx->uc_mcontext.gregs[14], regs[14], 16);
+  hexvalue (ctx->uc_mcontext.gregs[15], regs[15], 16);
+  hexvalue (ctx->uc_mcontext.psw.mask, regs[16], 16);
+  hexvalue (ctx->uc_mcontext.psw.addr, regs[17], 16);
 
   /* Generate the output.  */
   ADD_STRING ("Register dump:\n\n GPR0: ");
diff --git a/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h b/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
index 6f911fedfc..ebcbcbc5bf 100644
--- a/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
@@ -18,5 +18,11 @@ 
 
 #include <signal.h>
 
-#define SIGCONTEXT struct sigcontext *
-#define GET_PC(ctx)	((void *)((ctx)->sregs->regs.psw.addr))
+#ifdef __s390x__
+# define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) \
+				   (ctx))->uc_mcontext.psw.addr))
+#else
+/* s390 uses 31 bit addresses.  */
+# define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) \
+				   (ctx))->uc_mcontext.psw.addr & 0x7FFFFFFF))
+#endif
diff --git a/sysdeps/unix/sysv/linux/sh/profil-counter.h b/sysdeps/unix/sysv/linux/sh/profil-counter.h
deleted file mode 100644
index 691142bc74..0000000000
--- a/sysdeps/unix/sysv/linux/sh/profil-counter.h
+++ /dev/null
@@ -1,32 +0,0 @@ 
-/* Low-level statistical profiling support function.  Linux/SH version.
-   Copyright (C) 1996-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <signal.h>
-
-static void
-__profil_counter (int signo, int _a2, int _a3, int _a4, struct sigcontext sc)
-{
-  void *pc;
-  pc = (void *) sc.sc_pc;
-  profil_count (pc);
-
-  /* This is a hack to prevent the compiler from implementing the
-     above function call as a sibcall.  The sibcall would overwrite
-     the signal context.  */
-  asm volatile ("");
-}
diff --git a/sysdeps/unix/sysv/linux/sh/sh4/register-dump.h b/sysdeps/unix/sysv/linux/sh/register-dump.h
similarity index 62%
rename from sysdeps/unix/sysv/linux/sh/sh4/register-dump.h
rename to sysdeps/unix/sysv/linux/sh/register-dump.h
index a35012a9c5..3bcc998290 100644
--- a/sysdeps/unix/sysv/linux/sh/sh4/register-dump.h
+++ b/sysdeps/unix/sysv/linux/sh/register-dump.h
@@ -53,7 +53,7 @@  hexvalue (unsigned long int value, char *buf, size_t len)
 }
 
 static void
-register_dump (int fd, struct sigcontext *ctx)
+register_dump (int fd, struct ucontext_t *ctx)
 {
   char regs[22][8];
   struct iovec iov[22 * 2 + 34 * 2 + 2];
@@ -69,28 +69,28 @@  register_dump (int fd, struct sigcontext *ctx)
   ++nr
 
   /* Generate strings of register contents.  */
-  hexvalue (ctx->sc_regs[0], regs[0], 8);
-  hexvalue (ctx->sc_regs[1], regs[1], 8);
-  hexvalue (ctx->sc_regs[2], regs[2], 8);
-  hexvalue (ctx->sc_regs[3], regs[3], 8);
-  hexvalue (ctx->sc_regs[4], regs[4], 8);
-  hexvalue (ctx->sc_regs[5], regs[5], 8);
-  hexvalue (ctx->sc_regs[6], regs[6], 8);
-  hexvalue (ctx->sc_regs[7], regs[7], 8);
-  hexvalue (ctx->sc_regs[8], regs[8], 8);
-  hexvalue (ctx->sc_regs[9], regs[9], 8);
-  hexvalue (ctx->sc_regs[10], regs[10], 8);
-  hexvalue (ctx->sc_regs[11], regs[11], 8);
-  hexvalue (ctx->sc_regs[12], regs[12], 8);
-  hexvalue (ctx->sc_regs[13], regs[13], 8);
-  hexvalue (ctx->sc_regs[14], regs[14], 8);
-  hexvalue (ctx->sc_regs[15], regs[15], 8);
-  hexvalue (ctx->sc_macl, regs[16], 8);
-  hexvalue (ctx->sc_mach, regs[17], 8);
-  hexvalue (ctx->sc_pc, regs[18], 8);
-  hexvalue (ctx->sc_pr, regs[19], 8);
-  hexvalue (ctx->sc_gbr, regs[20], 8);
-  hexvalue (ctx->sc_sr, regs[21], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R0], regs[0], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R1], regs[1], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R2], regs[2], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R3], regs[3], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R4], regs[4], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R5], regs[5], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R6], regs[6], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R7], regs[7], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R8], regs[8], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R9], regs[9], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R10], regs[10], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R11], regs[11], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R12], regs[12], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R13], regs[13], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R14], regs[14], 8);
+  hexvalue (ctx->uc_mcontext.gregs[REG_R15], regs[15], 8);
+  hexvalue (ctx->uc_mcontext.macl, regs[16], 8);
+  hexvalue (ctx->uc_mcontext.mach, regs[17], 8);
+  hexvalue (ctx->uc_mcontext.pc, regs[18], 8);
+  hexvalue (ctx->uc_mcontext.pr, regs[19], 8);
+  hexvalue (ctx->uc_mcontext.gbr, regs[20], 8);
+  hexvalue (ctx->uc_mcontext.sr, regs[21], 8);
 
   /* Generate the output.  */
   ADD_STRING ("Register dump:\n\n  R0: ");
@@ -144,42 +144,42 @@  register_dump (int fd, struct sigcontext *ctx)
 
 #ifdef __SH_FPU_ANY__
   char fpregs[34][8];
-  if (ctx->sc_ownedfp != 0)
+  if (ctx->uc_mcontext.ownedfp != 0)
     {
-      hexvalue (ctx->sc_fpregs[0], fpregs[0], 8);
-      hexvalue (ctx->sc_fpregs[1], fpregs[1], 8);
-      hexvalue (ctx->sc_fpregs[2], fpregs[2], 8);
-      hexvalue (ctx->sc_fpregs[3], fpregs[3], 8);
-      hexvalue (ctx->sc_fpregs[4], fpregs[4], 8);
-      hexvalue (ctx->sc_fpregs[5], fpregs[5], 8);
-      hexvalue (ctx->sc_fpregs[6], fpregs[6], 8);
-      hexvalue (ctx->sc_fpregs[7], fpregs[7], 8);
-      hexvalue (ctx->sc_fpregs[8], fpregs[8], 8);
-      hexvalue (ctx->sc_fpregs[9], fpregs[9], 8);
-      hexvalue (ctx->sc_fpregs[10], fpregs[10], 8);
-      hexvalue (ctx->sc_fpregs[11], fpregs[11], 8);
-      hexvalue (ctx->sc_fpregs[12], fpregs[12], 8);
-      hexvalue (ctx->sc_fpregs[13], fpregs[13], 8);
-      hexvalue (ctx->sc_fpregs[14], fpregs[14], 8);
-      hexvalue (ctx->sc_fpregs[15], fpregs[15], 8);
-      hexvalue (ctx->sc_xfpregs[0], fpregs[16], 8);
-      hexvalue (ctx->sc_xfpregs[1], fpregs[17], 8);
-      hexvalue (ctx->sc_xfpregs[2], fpregs[18], 8);
-      hexvalue (ctx->sc_xfpregs[3], fpregs[19], 8);
-      hexvalue (ctx->sc_xfpregs[4], fpregs[20], 8);
-      hexvalue (ctx->sc_xfpregs[5], fpregs[21], 8);
-      hexvalue (ctx->sc_xfpregs[6], fpregs[22], 8);
-      hexvalue (ctx->sc_xfpregs[7], fpregs[23], 8);
-      hexvalue (ctx->sc_xfpregs[8], fpregs[24], 8);
-      hexvalue (ctx->sc_xfpregs[9], fpregs[25], 8);
-      hexvalue (ctx->sc_xfpregs[10], fpregs[26], 8);
-      hexvalue (ctx->sc_xfpregs[11], fpregs[27], 8);
-      hexvalue (ctx->sc_xfpregs[12], fpregs[28], 8);
-      hexvalue (ctx->sc_xfpregs[13], fpregs[29], 8);
-      hexvalue (ctx->sc_xfpregs[14], fpregs[30], 8);
-      hexvalue (ctx->sc_xfpregs[15], fpregs[31], 8);
-      hexvalue (ctx->sc_fpscr, fpregs[32], 8);
-      hexvalue (ctx->sc_fpul, fpregs[33], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[0], fpregs[0], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[1], fpregs[1], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[2], fpregs[2], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[3], fpregs[3], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[4], fpregs[4], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[5], fpregs[5], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[6], fpregs[6], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[7], fpregs[7], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[8], fpregs[8], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[9], fpregs[9], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[10], fpregs[10], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[11], fpregs[11], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[12], fpregs[12], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[13], fpregs[13], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[14], fpregs[14], 8);
+      hexvalue (ctx->uc_mcontext.fpregs[15], fpregs[15], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[0], fpregs[16], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[1], fpregs[17], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[2], fpregs[18], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[3], fpregs[19], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[4], fpregs[20], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[5], fpregs[21], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[6], fpregs[22], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[7], fpregs[23], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[8], fpregs[24], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[9], fpregs[25], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[10], fpregs[26], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[11], fpregs[27], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[12], fpregs[28], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[13], fpregs[29], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[14], fpregs[30], 8);
+      hexvalue (ctx->uc_mcontext.xfpregs[15], fpregs[31], 8);
+      hexvalue (ctx->uc_mcontext.fpscr, fpregs[32], 8);
+      hexvalue (ctx->uc_mcontext.fpul, fpregs[33], 8);
 
       ADD_STRING ("\n\n FR0: ");
       ADD_MEM (fpregs[0], 8);
@@ -260,4 +260,4 @@  register_dump (int fd, struct sigcontext *ctx)
 }
 
 
-#define REGISTER_DUMP register_dump (fd, &ctx)
+#define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h b/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h
deleted file mode 100644
index 137ba79c8c..0000000000
--- a/sysdeps/unix/sysv/linux/sh/sh3/register-dump.h
+++ /dev/null
@@ -1,150 +0,0 @@ 
-/* Dump registers.
-   Copyright (C) 1999-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sys/uio.h>
-#include <_itoa.h>
-
-/* We will print the register dump in this format:
-
-  R0: XXXXXXXX   R1: XXXXXXXX   R2: XXXXXXXX   R3: XXXXXXXX
-  R4: XXXXXXXX   R5: XXXXXXXX   R6: XXXXXXXX   R7: XXXXXXXX
-  R8: XXXXXXXX   R9: XXXXXXXX  R10: XXXXXXXX  R11: XXXXXXXX
- R12: XXXXXXXX  R13: XXXXXXXX  R14: XXXXXXXX  R15: XXXXXXXX
-
-MACL: XXXXXXXX MACH: XXXXXXXX
-
-  PC: XXXXXXXX   PR: XXXXXXXX  GBR: XXXXXXXX   SR: XXXXXXXX
-
- FR0: XXXXXXXX  FR1: XXXXXXXX  FR2: XXXXXXXX  FR3: XXXXXXXX
- FR4: XXXXXXXX  FR5: XXXXXXXX  FR6: XXXXXXXX  FR7: XXXXXXXX
- FR8: XXXXXXXX  FR9: XXXXXXXX FR10: XXXXXXXX FR11: XXXXXXXX
-FR12: XXXXXXXX FR13: XXXXXXXX FR14: XXXXXXXX FR15: XXXXXXXX
-
- XR0: XXXXXXXX  XR1: XXXXXXXX  XR2: XXXXXXXX  XR3: XXXXXXXX
- XR4: XXXXXXXX  XR5: XXXXXXXX  XR6: XXXXXXXX  XR7: XXXXXXXX
- XR8: XXXXXXXX  XR9: XXXXXXXX XR10: XXXXXXXX XR11: XXXXXXXX
-XR12: XXXXXXXX XR13: XXXXXXXX XR14: XXXXXXXX XR15: XXXXXXXX
-
-FPSCR: XXXXXXXX FPUL: XXXXXXXX
-
- */
-
-static void
-hexvalue (unsigned long int value, char *buf, size_t len)
-{
-  char *cp = _itoa_word (value, buf + len, 16, 0);
-  while (cp > buf)
-    *--cp = '0';
-}
-
-static void
-register_dump (int fd, struct sigcontext *ctx)
-{
-  char regs[22][8];
-  struct iovec iov[112];
-  size_t nr = 0;
-
-#define ADD_STRING(str) \
-  iov[nr].iov_base = (char *) str;					      \
-  iov[nr].iov_len = strlen (str);					      \
-  ++nr
-#define ADD_MEM(str, len) \
-  iov[nr].iov_base = str;						      \
-  iov[nr].iov_len = len;						      \
-  ++nr
-
-  /* Generate strings of register contents.  */
-  hexvalue (ctx->sc_regs[0], regs[0], 8);
-  hexvalue (ctx->sc_regs[1], regs[1], 8);
-  hexvalue (ctx->sc_regs[2], regs[2], 8);
-  hexvalue (ctx->sc_regs[3], regs[3], 8);
-  hexvalue (ctx->sc_regs[4], regs[4], 8);
-  hexvalue (ctx->sc_regs[5], regs[5], 8);
-  hexvalue (ctx->sc_regs[6], regs[6], 8);
-  hexvalue (ctx->sc_regs[7], regs[7], 8);
-  hexvalue (ctx->sc_regs[8], regs[8], 8);
-  hexvalue (ctx->sc_regs[9], regs[9], 8);
-  hexvalue (ctx->sc_regs[10], regs[10], 8);
-  hexvalue (ctx->sc_regs[11], regs[11], 8);
-  hexvalue (ctx->sc_regs[12], regs[12], 8);
-  hexvalue (ctx->sc_regs[13], regs[13], 8);
-  hexvalue (ctx->sc_regs[14], regs[14], 8);
-  hexvalue (ctx->sc_regs[15], regs[15], 8);
-  hexvalue (ctx->sc_macl, regs[16], 8);
-  hexvalue (ctx->sc_mach, regs[17], 8);
-  hexvalue (ctx->sc_pc, regs[18], 8);
-  hexvalue (ctx->sc_pr, regs[19], 8);
-  hexvalue (ctx->sc_gbr, regs[20], 8);
-  hexvalue (ctx->sc_sr, regs[21], 8);
-
-  /* Generate the output.  */
-  ADD_STRING ("Register dump:\n\n  R0: ");
-  ADD_MEM (regs[0], 8);
-  ADD_STRING ("   R1: ");
-  ADD_MEM (regs[1], 8);
-  ADD_STRING ("   R2: ");
-  ADD_MEM (regs[2], 8);
-  ADD_STRING ("   R3: ");
-  ADD_MEM (regs[3], 8);
-  ADD_STRING ("\n  R4: ");
-  ADD_MEM (regs[4], 8);
-  ADD_STRING ("   R5: ");
-  ADD_MEM (regs[5], 8);
-  ADD_STRING ("   R6: ");
-  ADD_MEM (regs[6], 8);
-  ADD_STRING ("   R7: ");
-  ADD_MEM (regs[7], 8);
-  ADD_STRING ("\n  R8: ");
-  ADD_MEM (regs[8], 8);
-  ADD_STRING ("   R9: ");
-  ADD_MEM (regs[9], 8);
-  ADD_STRING ("  R10: ");
-  ADD_MEM (regs[10], 8);
-  ADD_STRING ("  R11: ");
-  ADD_MEM (regs[11], 8);
-  ADD_STRING ("\n R12: ");
-  ADD_MEM (regs[12], 8);
-  ADD_STRING ("  R13: ");
-  ADD_MEM (regs[13], 8);
-  ADD_STRING ("  R14: ");
-  ADD_MEM (regs[14], 8);
-  ADD_STRING ("  R15: ");
-  ADD_MEM (regs[15], 8);
-
-  ADD_STRING ("\n\nMACL: ");
-  ADD_MEM (regs[16], 8);
-  ADD_STRING (" MACH: ");
-  ADD_MEM (regs[17], 8);
-
-  ADD_STRING ("\n\n  PC: ");
-  ADD_MEM (regs[18], 8);
-  ADD_STRING ("   PR: ");
-  ADD_MEM (regs[19], 8);
-  ADD_STRING ("  GBR: ");
-  ADD_MEM (regs[20], 8);
-  ADD_STRING ("   SR: ");
-  ADD_MEM (regs[21], 8);
-
-  ADD_STRING ("\n");
-
-  /* Write the stuff out.  */
-  writev (fd, iov, nr);
-}
-
-
-#define REGISTER_DUMP register_dump (fd, &ctx)
diff --git a/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h b/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
index d09dbea212..d369c31d60 100644
--- a/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
@@ -16,6 +16,4 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT int _a2, int _a3, int _a4, struct sigcontext
-
-#define GET_PC(ctx)	((void *) ctx.sc_pc)
+#define GET_PC(ctx) ((uintptr_t) (((ucontext_t *) (ctx))->uc_mcontext.pc))
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h b/sysdeps/unix/sysv/linux/sparc/profil-counter.h
similarity index 88%
rename from sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
rename to sysdeps/unix/sysv/linux/sparc/profil-counter.h
index 47f8bf94a1..b36db52651 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/sparc/profil-counter.h
@@ -16,13 +16,7 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <signal.h>
-
-void
-__profil_counter (int signo, struct sigcontext *si)
-{
-  profil_count ((void *) si->sigc_regs.tpc);
-}
+#include <sysdeps/unix/sysv/linux/profil-counter.h>
 #ifndef __profil_counter
 weak_alias (__profil_counter, profil_counter)
 #endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h b/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h
deleted file mode 100644
index 22abf93b1b..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h
+++ /dev/null
@@ -1,28 +0,0 @@ 
-/* Low-level statistical profiling support function.  Linux/SPARC version.
-   Copyright (C) 1997-2019 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <signal.h>
-
-void
-__profil_counter (int signo, struct sigcontext *si)
-{
-  profil_count ((void *) si->si_regs.pc);
-}
-#ifndef __profil_counter
-weak_alias (__profil_counter, profil_counter)
-#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h b/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h
index 209a6c9dac..9569c47f79 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/register-dump.h
@@ -84,16 +84,23 @@  struct __siginfo_sparc64_fpu
   unsigned int si_fprs;
 };
 
+/* Different that other architectures, SPARC32 pass a pt_regs (or pt_regs32
+   in 32 bits compat mode) struct pointer as third argument for sa_sigaction
+   handler with SA_SIGINFO.  */
 static void
-register_dump (int fd, SIGCONTEXT ctx)
+register_dump (int fd, void *ctx)
 {
   char regs[36][8];
   char fregs[68][8];
   struct iovec iov[150];
   size_t nr = 0;
   int i;
-  unsigned int *r = (unsigned int *)
-    ctx->si_regs.u_regs[14];
+  struct pt_regs32 *ptregs = (struct pt_regs32 *) ctx;
+  struct compat_sigset_t {                     
+    unsigned int sig[2];
+  };
+  struct compat_sigset_t *mask = (struct compat_sigset_t *)(ptregs + 1);
+  unsigned int *r = (unsigned int *) ptregs->u_regs[14];
 
 #define ADD_STRING(str) \
   iov[nr].iov_base = (char *) str;					      \
@@ -105,15 +112,16 @@  register_dump (int fd, SIGCONTEXT ctx)
   ++nr
 
   /* Generate strings of register contents.  */
-  hexvalue (ctx->si_regs.psr, regs[0], 8);
-  hexvalue (ctx->si_regs.pc, regs[1], 8);
-  hexvalue (ctx->si_regs.npc, regs[2], 8);
-  hexvalue (ctx->si_regs.y, regs[3], 8);
+  hexvalue (ptregs->psr, regs[0], 8);
+  hexvalue (ptregs->pc, regs[1], 8);
+  hexvalue (ptregs->npc, regs[2], 8);
+  hexvalue (ptregs->y, regs[3], 8);
   for (i = 1; i <= 15; i++)
-    hexvalue (ctx->si_regs.u_regs[i], regs[3+i], 8);
+    hexvalue (ptregs->u_regs[i], regs[3+i], 8);
   for (i = 0; i <= 15; i++)
     hexvalue (r[i], regs[19+i], 8);
-  hexvalue (ctx->si_mask, regs[35], 8);
+
+  hexvalue (mask->sig[0], regs[35], 8);
 
   /* Generate the output.  */
   ADD_STRING ("Register dump:\n\n PSR: ");
@@ -189,11 +197,11 @@  register_dump (int fd, SIGCONTEXT ctx)
   ADD_STRING ("\n\n Old mask: ");
   ADD_MEM (regs[35], 8);
 
-  if ((ctx->si_regs.psr & 0xff000000) == 0xff000000)
+  if ((ptregs->psr & 0xff000000) == 0xff000000)
     {
-      struct __siginfo_sparc64_fpu *f;
+      struct __siginfo_sparc64_fpu *f = *(struct __siginfo_sparc64_fpu **)
+	(mask + 1);
 
-      f = *(struct __siginfo_sparc64_fpu **) (ctx + 1);
       if (f != NULL)
 	{
 	  for (i = 0; i < 64; i++)
@@ -277,9 +285,9 @@  register_dump (int fd, SIGCONTEXT ctx)
     }
   else
     {
-      struct __siginfo_sparc32_fpu *f;
+      struct __siginfo_sparc32_fpu *f = *(struct __siginfo_sparc32_fpu **)
+	(mask + 1);
 
-      f = *(struct __siginfo_sparc32_fpu **) (ctx + 1);
       if (f != NULL)
 	{
 	  for (i = 0; i < 32; i++)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
index 9eec807a23..af1bcd21e2 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
@@ -16,5 +16,38 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT struct sigcontext *
-#define GET_PC(__ctx)	((void *) ((__ctx)->si_regs.pc))
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+/* The kernel sparc32 signal frame for SA_SIGINFO is layout as:
+
+  struct rt_signal_frame32 {
+   struct sparc_stackf32 ss;
+   compat_siginfo_t info;
+   struct pt_regs32 regs;
+   compat_sigset_t mask;   
+   u32 fpu_save;
+   unsigned int insns[2];
+   compat_stack_t stack;
+   unsigned int extra_size;
+   siginfo_extra_v8plus_t v8plus;
+   u32 rwin_save;
+  } __attribute__((aligned(8)));
+
+
+  And different that other architectures, SPARC32 pass the pt_regs32
+  REGS pointer as third argument for sa_sigaction handler with 
+  SA_SIGINFO.  */
+
+struct pt_regs32
+{
+  unsigned int psr;
+  unsigned int pc;
+  unsigned int npc;
+  unsigned int y;
+  unsigned int u_regs[16];
+};
+
+#define GET_PC(ctx) ((uintptr_t)(((struct pt_regs32 *) (ctx))->pc))
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h b/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h
index 0f1078ad9e..722f06e09d 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/register-dump.h
@@ -60,17 +60,36 @@  hexvalue (unsigned long int value, char *buf, size_t len)
     *--cp = '0';
 }
 
+/* Different that other architectures, SPARC32 pass a pt_regs (or pt_regs32
+   in 32 bits compat mode) struct pointer as third argument for sa_sigaction
+   handler with SA_SIGINFO.
+
+   The kernel sigframe for SA_SIGINFO is setup as:
+
+   struct rt_signal_frame {
+     struct sparc_stackf ss;
+     siginfo_t info;
+     struct pt_regs regs;          <- void *ctx
+     __siginfo_fpu_t *fpu_save;
+     stack_t stack;
+     sigset_t mask;
+     __siginfo_rwin_t *rwin_save;
+   };
+*/
 static void
-register_dump (int fd, SIGCONTEXT ctx)
+register_dump (int fd, void *ctx)
 {
   char regs[36][16];
   char fregs[68][8];
   struct iovec iov[150];
   size_t nr = 0;
   int i;
-  unsigned long *r = (unsigned long *)
-    (ctx->sigc_regs.u_regs[14] + STACK_BIAS);
-  __siginfo_fpu_t *f;
+  struct pt_regs *ptregs = (struct pt_regs*) ((siginfo_t *)ctx + 1);
+  unsigned long *r = (unsigned long *) (ptregs->u_regs[14] + STACK_BIAS);
+  __siginfo_fpu_t *f = (__siginfo_fpu_t *)(ptregs + 1);
+  struct kernel_sigset_t {
+    unsigned long sig[1];
+  } *mask = (struct kernel_sigset_t *)((stack_t *)(f + 1) + 1);
 
 #define ADD_STRING(str) \
   iov[nr].iov_base = (char *) str;					      \
@@ -82,15 +101,15 @@  register_dump (int fd, SIGCONTEXT ctx)
   ++nr
 
   /* Generate strings of register contents.  */
-  hexvalue (ctx->sigc_regs.tstate,	regs[0], 16);
-  hexvalue (ctx->sigc_regs.tpc,		regs[1], 16);
-  hexvalue (ctx->sigc_regs.tnpc,	regs[2], 16);
-  hexvalue (ctx->sigc_regs.y,		regs[3], 8);
+  hexvalue (ptregs->tstate, regs[0], 16);
+  hexvalue (ptregs->tpc, regs[1], 16);
+  hexvalue (ptregs->tnpc, regs[2], 16);
+  hexvalue (ptregs->y, regs[3], 8);
   for (i = 1; i <= 15; i++)
-    hexvalue (ctx->sigc_regs.u_regs[i], regs[3+i], 16);
+    hexvalue (ptregs->u_regs[i], regs[3+i], 16);
   for (i = 0; i <= 15; i++)
-    hexvalue (r[i],			regs[19+i], 16);
-  hexvalue (ctx->sigc_mask,		regs[35], 16);
+    hexvalue (r[i], regs[19+i], 16);
+  hexvalue (mask->sig[0], regs[35], 16);
 
   /* Generate the output.  */
   ADD_STRING ("Register dump:\n\n TSTATE: ");
@@ -166,7 +185,6 @@  register_dump (int fd, SIGCONTEXT ctx)
   ADD_STRING ("\n\n Mask: ");
   ADD_MEM (regs[35], 16);
 
-  f = ctx->sigc_fpu_save;
   if (f != NULL)
     {
       for (i = 0; i < 64; i++)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
index a2f2b1f7de..744b51c585 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
@@ -16,8 +16,45 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+#include <bits/types/siginfo_t.h>
+
+/* The kernel sparc64 signal frame for SA_SIGINFO is layout as:
+
+   struct rt_signal_frame {
+     struct sparc_stackf ss;
+     siginfo_t info;
+     struct pt_regs regs; 
+     __siginfo_fpu_t *fpu_save;
+     stack_t stack;
+     sigset_t mask;
+     __siginfo_rwin_t *rwin_save; 
+   };
+
+   And different that other architectures, SPARC64 pass the siginfo_t
+   INFO pointer as third argument for sa_sigaction handler with 
+   SA_SIGINFO.  */
+
 #ifndef STACK_BIAS
 #define STACK_BIAS 2047
 #endif
-#define SIGCONTEXT struct sigcontext *
-#define GET_PC(__ctx)	((void *) ((__ctx)->sigc_regs.tpc))
+
+struct pt_regs
+{
+ unsigned long u_regs[16];
+ unsigned long tstate;
+ unsigned long tpc;
+ unsigned long tnpc;
+ unsigned int y;
+ unsigned int magic;
+}; 
+
+#define GET_PC(ctx) \
+  ({									\
+    struct pt_regs *regs = (struct pt_regs*) ((siginfo_t *)(ctx) + 1);	\
+    (uintptr_t) regs->tpc;						\
+  })
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
index 630f3992eb..0f3b8e8864 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
@@ -15,8 +15,5 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <stdint.h>
-
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-#define GET_PC(ctx)	\
-  ((void *) (uintptr_t) (ctx)->uc_mcontext.gregs[REG_RIP])
+#define GET_PC(ctx) ((intptr_t) (((ucontext_t *) \
+		     (ctx))->uc_mcontext.gregs[REG_RIP]))