[PATCH v2 1/2] Refactor sigcontextinfo.h

classic Classic list List threaded Threaded
33 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[PATCH v2 1/2] Refactor sigcontextinfo.h

Adhemerval Zanella-2
Changes from previous version:

  - For arm and sparc the profil_counter requires to be exported (it is
    part of the ABIs, check BZ#17726).  The arm implementation can't be
    local and sparc uses the old signal handler signature.

This is the last refactor required for BZ#12683 fix, I will like to get
this upstream to move foward with BZ#12683.

--

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 suppress compiler warnings).

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

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

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

   - sparc 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.

        * 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  |   4 +-
 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      |  14 +-
 .../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, 706 insertions(+), 975 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 (77%)
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc32/profil-counter.h

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..29a9c7fecc 100644
--- a/sysdeps/unix/sysv/linux/arm/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/arm/profil-counter.h
@@ -20,9 +20,9 @@
 #include <sigcontextinfo.h>
 
 void
-__profil_counter (int signo, const SIGCONTEXT scp)
+__profil_counter (int signo, siginfo_t *_si, void *scp)
 {
-  profil_count ((void *) GET_PC (scp));
+  profil_count (GET_PC (scp));
 
   /* 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/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 77%
rename from sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
rename to sysdeps/unix/sysv/linux/sparc/profil-counter.h
index 47f8bf94a1..ad06a4fe06 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/sparc/profil-counter.h
@@ -18,11 +18,17 @@
 
 #include <signal.h>
 
+#include <sysdeps/unix/sysv/linux/profil-counter.h>
+
+#ifndef __profil_counter
 void
-__profil_counter (int signo, struct sigcontext *si)
+__profil_counter_global (int signo, struct sigcontext *si)
 {
-  profil_count ((void *) si->sigc_regs.tpc);
+#ifdef __arch64__
+  profil_count (si->sigc_regs.tpc);
+#else
+  profil_count (si->si_regs.pc);
+#endif
 }
-#ifndef __profil_counter
-weak_alias (__profil_counter, profil_counter)
+weak_alias (__profil_counter_global, 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]))
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

[PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Adhemerval Zanella-2
As indicated by Joseph's comment on BZ#17726, this symbol is most
likely a historical ABI accident.  This patch make it on both arm
and sparc ABIs a compat_symbol.

Checked with a build arm-linux-gnueabihf, sparcv9-linux-gnu, adn
sparc64-linux-gnu to see if the symbol is still present.

        * gmon/Versions (libc) [GLIBC_2.31]: New entry.
        * sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter):
        Make a compat_symbol.
        * sysdeps/unix/sysv/linux/sparc/profil-counter.h
        (__profil_counter_global): Likewise.
---
 gmon/Versions                                  | 2 ++
 sysdeps/unix/sysv/linux/arm/profil-counter.h   | 5 ++++-
 sysdeps/unix/sysv/linux/sparc/profil-counter.h | 5 ++++-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/gmon/Versions b/gmon/Versions
index d0b63334f2..cc705bd978 100644
--- a/gmon/Versions
+++ b/gmon/Versions
@@ -19,4 +19,6 @@ libc {
   GLIBC_2.2.3 {
     sprofil;
   }
+  GLIBC_2.31 {
+  }
 }
diff --git a/sysdeps/unix/sysv/linux/arm/profil-counter.h b/sysdeps/unix/sysv/linux/arm/profil-counter.h
index 29a9c7fecc..6243a02bb5 100644
--- a/sysdeps/unix/sysv/linux/arm/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/arm/profil-counter.h
@@ -30,5 +30,8 @@ __profil_counter (int signo, siginfo_t *_si, void *scp)
   asm volatile ("");
 }
 #ifndef __profil_counter
-weak_alias (__profil_counter, profil_counter)
+# include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_31)
+compat_symbol (libc, __profil_counter, profil_counter, GLIBC_2_0);
+# endif
 #endif
diff --git a/sysdeps/unix/sysv/linux/sparc/profil-counter.h b/sysdeps/unix/sysv/linux/sparc/profil-counter.h
index ad06a4fe06..01271103bb 100644
--- a/sysdeps/unix/sysv/linux/sparc/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/sparc/profil-counter.h
@@ -21,6 +21,8 @@
 #include <sysdeps/unix/sysv/linux/profil-counter.h>
 
 #ifndef __profil_counter
+# include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_31)
 void
 __profil_counter_global (int signo, struct sigcontext *si)
 {
@@ -30,5 +32,6 @@ __profil_counter_global (int signo, struct sigcontext *si)
   profil_count (si->si_regs.pc);
 #endif
 }
-weak_alias (__profil_counter_global, profil_counter)
+compat_symbol (libc, __profil_counter_global, profil_counter, GLIBC_2_0);
+# endif
 #endif
--
2.17.1

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Florian Weimer-5
* Adhemerval Zanella:

> As indicated by Joseph's comment on BZ#17726, this symbol is most
> likely a historical ABI accident.  This patch make it on both arm
> and sparc ABIs a compat_symbol.
>
> Checked with a build arm-linux-gnueabihf, sparcv9-linux-gnu, adn
> sparc64-linux-gnu to see if the symbol is still present.
>
> * gmon/Versions (libc) [GLIBC_2.31]: New entry.
> * sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter):
> Make a compat_symbol.
> * sysdeps/unix/sysv/linux/sparc/profil-counter.h
> (__profil_counter_global): Likewise.

There is this bug:

  <https://sourceware.org/bugzilla/show_bug.cgi?id=14043>

So it was already gone for over four years on arm until someone noticed.
I wonder if something really needs it?

Thanks,
Florian
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Adhemerval Zanella-2


On 02/08/2019 08:09, Florian Weimer wrote:

> * Adhemerval Zanella:
>
>> As indicated by Joseph's comment on BZ#17726, this symbol is most
>> likely a historical ABI accident.  This patch make it on both arm
>> and sparc ABIs a compat_symbol.
>>
>> Checked with a build arm-linux-gnueabihf, sparcv9-linux-gnu, adn
>> sparc64-linux-gnu to see if the symbol is still present.
>>
>> * gmon/Versions (libc) [GLIBC_2.31]: New entry.
>> * sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter):
>> Make a compat_symbol.
>> * sysdeps/unix/sysv/linux/sparc/profil-counter.h
>> (__profil_counter_global): Likewise.
>
> There is this bug:
>
>   <https://sourceware.org/bugzilla/show_bug.cgi?id=14043>
>
> So it was already gone for over four years on arm until someone noticed.
> I wonder if something really needs it?

My take on this accidental ABI leakage is just to dropped it, it exposes
unnecessary implementation detail, add complexity on arch-specific code
base, it is dangerous because pollute application namespace with non
expected symbol, and I would consider a potential bug if application are
relying on this specific symbol semantic (and it is also non-portable).

So I would vote if we just remove it instead of make it a compat symbol.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Florian Weimer-5
* Adhemerval Zanella:

> On 02/08/2019 08:09, Florian Weimer wrote:
>> * Adhemerval Zanella:
>>
>>> As indicated by Joseph's comment on BZ#17726, this symbol is most
>>> likely a historical ABI accident.  This patch make it on both arm
>>> and sparc ABIs a compat_symbol.
>>>
>>> Checked with a build arm-linux-gnueabihf, sparcv9-linux-gnu, adn
>>> sparc64-linux-gnu to see if the symbol is still present.
>>>
>>> * gmon/Versions (libc) [GLIBC_2.31]: New entry.
>>> * sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter):
>>> Make a compat_symbol.
>>> * sysdeps/unix/sysv/linux/sparc/profil-counter.h
>>> (__profil_counter_global): Likewise.
>>
>> There is this bug:
>>
>>   <https://sourceware.org/bugzilla/show_bug.cgi?id=14043>
>>
>> So it was already gone for over four years on arm until someone noticed.
>> I wonder if something really needs it?
>
> My take on this accidental ABI leakage is just to dropped it, it exposes
> unnecessary implementation detail, add complexity on arch-specific code
> base, it is dangerous because pollute application namespace with non
> expected symbol, and I would consider a potential bug if application are
> relying on this specific symbol semantic (and it is also non-portable).
>
> So I would vote if we just remove it instead of make it a compat symbol.

I tend to agree, but I wonder if Joseph filed this bug because it was
something that someone actually encountered as the result of a glibc
update.  In this case, it strongly points to accidental use of the
symbol.

I'm not necessarily opposed to actually removing symbols from the ABI in
general.  (I think some of us are though.)  I'm wondering if we have
evidence that we can't do it here.

Thanks,
Florian
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Joseph Myers
On Fri, 2 Aug 2019, Florian Weimer wrote:

> I tend to agree, but I wonder if Joseph filed this bug because it was
> something that someone actually encountered as the result of a glibc
> update.  In this case, it strongly points to accidental use of the
> symbol.

I filed the bug because, when we were setting up the ABI test baselines in
the first place, it seemed desirable to verify them against binaries built
from various past glibc versions (to check as far as possible that the
contents of each symbol version in the test expectations were the same as
the contents of that version in the corresponding glibc release), and
doing such verification showed up that symbol as having been accidentally
removed.

(I did remove the _q_* symbols from powerpc soft-float; those had, in
glibc 2.4, been accidentally added to version GLIBC_2.2, but had never
been usefully usable - and made the baseline there reflect the accidental
removal of __fe_nomask_env which had also never been usable for that
configuration.)

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Adhemerval Zanella-2


On 02/08/2019 12:48, Joseph Myers wrote:

> On Fri, 2 Aug 2019, Florian Weimer wrote:
>
>> I tend to agree, but I wonder if Joseph filed this bug because it was
>> something that someone actually encountered as the result of a glibc
>> update.  In this case, it strongly points to accidental use of the
>> symbol.
>
> I filed the bug because, when we were setting up the ABI test baselines in
> the first place, it seemed desirable to verify them against binaries built
> from various past glibc versions (to check as far as possible that the
> contents of each symbol version in the test expectations were the same as
> the contents of that version in the corresponding glibc release), and
> doing such verification showed up that symbol as having been accidentally
> removed.
>
> (I did remove the _q_* symbols from powerpc soft-float; those had, in
> glibc 2.4, been accidentally added to version GLIBC_2.2, but had never
> been usefully usable - and made the baseline there reflect the accidental
> removal of __fe_nomask_env which had also never been usable for that
> configuration.)
>

So do you think we can remove them or should we keep them? I do think
we should just remove these accidental bleeding symbols.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Joseph Myers
On Fri, 2 Aug 2019, Adhemerval Zanella wrote:

> So do you think we can remove them or should we keep them? I do think
> we should just remove these accidental bleeding symbols.

I think there is a strong presumption in favour of keeping symbols that
were public in a (2.1 or later, i.e. after the introduction of symbol
versioning) release, in the absence of clear evidence that the symbol
would never have been usable.

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Carlos O'Donell-6
On 8/2/19 3:55 PM, Joseph Myers wrote:
> On Fri, 2 Aug 2019, Adhemerval Zanella wrote:
>
>> So do you think we can remove them or should we keep them? I do think
>> we should just remove these accidental bleeding symbols.
>
> I think there is a strong presumption in favour of keeping symbols that
> were public in a (2.1 or later, i.e. after the introduction of symbol
> versioning) release, in the absence of clear evidence that the symbol
> would never have been usable.

Agreed. Compat is safe enough.

--
Cheers,
Carlos.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Florian Weimer-5
* Carlos O'Donell:

> On 8/2/19 3:55 PM, Joseph Myers wrote:
>> On Fri, 2 Aug 2019, Adhemerval Zanella wrote:
>>
>>> So do you think we can remove them or should we keep them? I do think
>>> we should just remove these accidental bleeding symbols.
>>
>> I think there is a strong presumption in favour of keeping symbols that
>> were public in a (2.1 or later, i.e. after the introduction of symbol
>> versioning) release, in the absence of clear evidence that the symbol
>> would never have been usable.
>
> Agreed. Compat is safe enough.

I think Adhemerval's point is that it adds complexity because it
requires support in the tree, for all architecturs, for something that
would otherwise be unneeded.  If we can avoid that, it's a win for us.

Thanks,
Florian
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Adhemerval Zanella-2


On 05/08/2019 06:53, Florian Weimer wrote:

> * Carlos O'Donell:
>
>> On 8/2/19 3:55 PM, Joseph Myers wrote:
>>> On Fri, 2 Aug 2019, Adhemerval Zanella wrote:
>>>
>>>> So do you think we can remove them or should we keep them? I do think
>>>> we should just remove these accidental bleeding symbols.
>>>
>>> I think there is a strong presumption in favour of keeping symbols that
>>> were public in a (2.1 or later, i.e. after the introduction of symbol
>>> versioning) release, in the absence of clear evidence that the symbol
>>> would never have been usable.
>>
>> Agreed. Compat is safe enough.
>
> I think Adhemerval's point is that it adds complexity because it
> requires support in the tree, for all architecturs, for something that
> would otherwise be unneeded.  If we can avoid that, it's a win for us.

Also that this symbol export was not meant in first place, so it is unlikely
programs uses it.  And if it were, it likely they either need to reference
to glibc implementation to get the correct prototype or it is bleeding in
application namespace wrongly, which is most likely.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Joseph Myers
On Mon, 5 Aug 2019, Adhemerval Zanella wrote:

> Also that this symbol export was not meant in first place, so it is unlikely

Like all other exports, it's listed in a Versions file.  So it must have
been deliberate (even if mistaken) at some point.

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Florian Weimer
* Joseph Myers:

> On Mon, 5 Aug 2019, Adhemerval Zanella wrote:
>
>> Also that this symbol export was not meant in first place, so it is unlikely
>
> Like all other exports, it's listed in a Versions file.  So it must have
> been deliberate (even if mistaken) at some point.

libc.map used to have this:

    # all functions and variables in the normal name space
    a*; b*; c*; d*; e*; f*; g*; h*; i*; j*; k*; l*; m*;
    n*; o*; p*; q*; r*; s*; t*; u*; v*; w*; x*; y*; z*;

So the missing static likely triggered the unwanted export, and that
mistake was carried over when libc.map was switched over to explicit
function names.  I do not see evidence of a deliberate decision here.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Carlos O'Donell-6
On 8/5/19 3:41 PM, Florian Weimer wrote:

> * Joseph Myers:
>
>> On Mon, 5 Aug 2019, Adhemerval Zanella wrote:
>>
>>> Also that this symbol export was not meant in first place, so it is unlikely
>>
>> Like all other exports, it's listed in a Versions file.  So it must have
>> been deliberate (even if mistaken) at some point.
>
> libc.map used to have this:
>
>      # all functions and variables in the normal name space
>      a*; b*; c*; d*; e*; f*; g*; h*; i*; j*; k*; l*; m*;
>      n*; o*; p*; q*; r*; s*; t*; u*; v*; w*; x*; y*; z*;
>
> So the missing static likely triggered the unwanted export, and that
> mistake was carried over when libc.map was switched over to explicit
> function names.  I do not see evidence of a deliberate decision here.
 
This is why we say "strong presumption" :-)

We want to err on the side of being cautious unless we have evidence
otherwise.

If there is no evidence that a deliberate and conscious decision was
made, then perhaps simplifying the situation may be fine e.g. no compat
symbols.

--
Cheers,
Carlos.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Florian Weimer
* Carlos O'Donell:

> On 8/5/19 3:41 PM, Florian Weimer wrote:
>> * Joseph Myers:
>>
>>> On Mon, 5 Aug 2019, Adhemerval Zanella wrote:
>>>
>>>> Also that this symbol export was not meant in first place, so it is unlikely
>>>
>>> Like all other exports, it's listed in a Versions file.  So it must have
>>> been deliberate (even if mistaken) at some point.
>>
>> libc.map used to have this:
>>
>>      # all functions and variables in the normal name space
>>      a*; b*; c*; d*; e*; f*; g*; h*; i*; j*; k*; l*; m*;
>>      n*; o*; p*; q*; r*; s*; t*; u*; v*; w*; x*; y*; z*;
>>
>> So the missing static likely triggered the unwanted export, and that
>> mistake was carried over when libc.map was switched over to explicit
>> function names.  I do not see evidence of a deliberate decision here.
>  
> This is why we say "strong presumption" :-)
>
> We want to err on the side of being cautious unless we have evidence
> otherwise.
>
> If there is no evidence that a deliberate and conscious decision was
> made, then perhaps simplifying the situation may be fine e.g. no compat
> symbols.

And if necessary, we can add back the symbol again.  As far as
mistakes go, it wouldn't even be that costly, I think.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Carlos O'Donell-6
On 8/6/19 3:18 PM, Florian Weimer wrote:

> * Carlos O'Donell:
>
>> On 8/5/19 3:41 PM, Florian Weimer wrote:
>>> * Joseph Myers:
>>>
>>>> On Mon, 5 Aug 2019, Adhemerval Zanella wrote:
>>>>
>>>>> Also that this symbol export was not meant in first place, so it is unlikely
>>>>
>>>> Like all other exports, it's listed in a Versions file.  So it must have
>>>> been deliberate (even if mistaken) at some point.
>>>
>>> libc.map used to have this:
>>>
>>>       # all functions and variables in the normal name space
>>>       a*; b*; c*; d*; e*; f*; g*; h*; i*; j*; k*; l*; m*;
>>>       n*; o*; p*; q*; r*; s*; t*; u*; v*; w*; x*; y*; z*;
>>>
>>> So the missing static likely triggered the unwanted export, and that
>>> mistake was carried over when libc.map was switched over to explicit
>>> function names.  I do not see evidence of a deliberate decision here.
>>    
>> This is why we say "strong presumption" :-)
>>
>> We want to err on the side of being cautious unless we have evidence
>> otherwise.
>>
>> If there is no evidence that a deliberate and conscious decision was
>> made, then perhaps simplifying the situation may be fine e.g. no compat
>> symbols.
>
> And if necessary, we can add back the symbol again.  As far as
> mistakes go, it wouldn't even be that costly, I think.

Just to be clear I have no sustained objection to this change, but also
no strong opinion one way or the other.

My point is only that I would like to see, what you have provided,
which is evidence that this is entirely a historical mistake.

I think that if Adhemerval proposes the patch, you review it, and nobody
objects, then we should just check it in. As you say we can add a compat
symbol later. We know we want to remove it.

--
Cheers,
Carlos.
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 2/2] linux: Make profil_counter a compat_symbol (BZ#17726)

Joseph Myers
On Tue, 6 Aug 2019, Carlos O'Donell wrote:

> Just to be clear I have no sustained objection to this change, but also
> no strong opinion one way or the other.

I am also not making a sustained objection here, just stating the general
(rebuttable) presumption that a symbol exported at a public symbol version
in a release should be kept even if it was a mistake to export it, in the
absence of strong evidence that removing it is safe.

--
Joseph S. Myers
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 1/2] Refactor sigcontextinfo.h

Florian Weimer-5
In reply to this post by Adhemerval Zanella-2
* Adhemerval Zanella:

> +/* 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; \
> +  })

The comment does not match the code: sigcontext_t vs struct sigcontext.

Thanks,
Florian
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 1/2] Refactor sigcontextinfo.h

Florian Weimer-5
In reply to this post by Adhemerval Zanella-2
I did this:

-#define GET_PC(ctx) ((intptr_t) (((ucontext_t *) \
+#define GET_PC(ctx) (1 + (intptr_t) (((ucontext_t *) \
      (ctx))->uc_mcontext.gregs[REG_RIP]))

And none of the existing x86-64 tests failed. 8-(

So I strongly urge you to add a test like the one below.  I can commit
it separately after your patch.  I still need to verify that it builds
on all architectures.

Thanks,
Florian
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 1/2] Refactor sigcontextinfo.h

Adhemerval Zanella-2
In reply to this post by Florian Weimer-5


On 15/08/2019 08:24, Florian Weimer wrote:

> * Adhemerval Zanella:
>
>> +/* 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; \
>> +  })
>
> The comment does not match the code: sigcontext_t vs struct sigcontext.

Indeed, I will correct the comment to reference 'struct sigcontext'.
12