Patchwork [v2,1/2] Refactor sigcontextinfo.h

login
register
mail settings
Submitter Adhemerval Zanella Netto
Date Aug. 1, 2019, 6:15 p.m.
Message ID <20190801181534.8802-1-adhemerval.zanella@linaro.org>
Download mbox | patch
Permalink /patch/33907/
State New
Headers show

Comments

Adhemerval Zanella Netto - Aug. 1, 2019, 6:15 p.m.
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
Florian Weimer - Aug. 15, 2019, 11:24 a.m.
* 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
Adhemerval Zanella Netto - Aug. 15, 2019, 1:44 p.m.
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'.
Florian Weimer - Aug. 15, 2019, 2:07 p.m.
* Adhemerval Zanella:

> 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:

“is defined 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)));

Isn't it GNU style to put the { on a line by itself (unindenteed)?
This is also relevant to the code, see struct kernel_sigset_t a bit
below in the posted patch.

> +  And different that other architectures, SPARC32 pass the pt_regs32
> +  REGS pointer as third argument for sa_sigaction handler with 
> +  SA_SIGINFO.  */

“Unlike other architectures, sparc32 passes pt_regs32 REGS pointers as
the third argument to a sa_sigaction handler with SA_SIGINFO enabled.”
or something like that?

“Different that” appears in a few other places as well which also need
fixing.

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

I think this is the sparc64 header, so the comment needs to be adjusted.

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

Wrong indentation, and “unsigned long int” should be used.

The patch has trailing whitespace in a few places, FWIW.

Overall, I'm in favor of this change.  I do wonder if GET_PC should be
an inline function instead, so that we get type checking for its
argument (even if the implementation needs to cast the pointer to
something else).

Thnaks,
Florian
Adhemerval Zanella Netto - Aug. 15, 2019, 5:56 p.m.
On 15/08/2019 11:07, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> 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:
> 
> “is defined as”?

Ack, I will use your suggestion.

> 
>> +  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)));
> 
> Isn't it GNU style to put the { on a line by itself (unindenteed)?
> This is also relevant to the code, see struct kernel_sigset_t a bit
> below in the posted patch.

Well this is copies from kernel source (arch/sparc/kernel/signal32.c:59),
I will change to GNU style.

> 
>> +  And different that other architectures, SPARC32 pass the pt_regs32
>> +  REGS pointer as third argument for sa_sigaction handler with 
>> +  SA_SIGINFO.  */
> 
> “Unlike other architectures, sparc32 passes pt_regs32 REGS pointers as
> the third argument to a sa_sigaction handler with SA_SIGINFO enabled.”
> or something like that?

Ack, I changed to your suggestion.

> 
> “Different that” appears in a few other places as well which also need
> fixing.

Ack (it seems it appears on ia64 and sparc64 as well, I changed them too).

> 
>> 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.
> 
> I think this is the sparc64 header, so the comment needs to be adjusted.

Ack, I used a similar text you suggested for sparc32.

> 
>> 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.  */


Btw, I used a similar text you suggested for sparc32.

>> +
>>  #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;
>> +}; 
> 
> Wrong indentation, and “unsigned long int” should be used.

Ack.

> 
> The patch has trailing whitespace in a few places, FWIW.

Ack.

> 
> Overall, I'm in favor of this change.  I do wonder if GET_PC should be
> an inline function instead, so that we get type checking for its
> argument (even if the implementation needs to cast the pointer to
> something else).

Good suggestion, I will change to an inline function.

Patch

diff --git a/debug/segfault.c b/debug/segfault.c
index bd1008d9af..1782211fec 100644
--- a/debug/segfault.c
+++ b/debug/segfault.c
@@ -35,6 +35,10 @@ 
    passed up by the signal handler.  */
 #include <sigcontextinfo.h>
 
+#ifdef SA_SIGINFO
+# define SIGCONTEXT siginfo_t *info, void *
+#endif
+
 /* Get code to possibly dump the content of all registers.  */
 #include <register-dump.h>
 
@@ -148,9 +152,15 @@  install_handler (void)
   const char *sigs = getenv ("SEGFAULT_SIGNALS");
   const char *name;
 
-  sa.sa_handler = (void *) catch_segfault;
+#ifdef SA_SIGINFO
+  sa.sa_sigaction = catch_segfault;
+  sa.sa_flags = SA_SIGINFO;
+#else
+  sa.sa_handler = (void*) catch_segfault;
+  sa.sa_flags = 0;
+#endif
   sigemptyset (&sa.sa_mask);
-  sa.sa_flags = SA_RESTART;
+  sa.sa_flags |= SA_RESTART;
 
   /* Maybe we are expected to use an alternative stack.  */
   if (getenv ("SEGFAULT_USE_ALTSTACK") != 0)
diff --git a/sysdeps/generic/profil-counter.h b/sysdeps/generic/profil-counter.h
index 6d3164e101..02de4f795f 100644
--- a/sysdeps/generic/profil-counter.h
+++ b/sysdeps/generic/profil-counter.h
@@ -22,5 +22,5 @@ 
 static void
 __profil_counter (int signr, int code, struct sigcontext *scp)
 {
-  profil_count ((void *) scp->sc_pc);
+  profil_count ((uintptr_t) scp->sc_pc);
 }
diff --git a/sysdeps/generic/sigcontextinfo.h b/sysdeps/generic/sigcontextinfo.h
index ff63a09043..b2ef5ea457 100644
--- a/sysdeps/generic/sigcontextinfo.h
+++ b/sysdeps/generic/sigcontextinfo.h
@@ -18,4 +18,4 @@ 
 
 /* In general we cannot provide any information.  */
 #define SIGCONTEXT struct sigcontext *
-#define GET_PC(ctx)	((void *) 0)
+#define GET_PC(ctx)	((uintptr_t) 0)
diff --git a/sysdeps/mach/hurd/i386/sigcontextinfo.h b/sysdeps/mach/hurd/i386/sigcontextinfo.h
index 65bf12976d..016ea4680f 100644
--- a/sysdeps/mach/hurd/i386/sigcontextinfo.h
+++ b/sysdeps/mach/hurd/i386/sigcontextinfo.h
@@ -16,4 +16,4 @@ 
    <http://www.gnu.org/licenses/>.  */
 
 #define SIGCONTEXT struct sigcontext
-#define GET_PC(ctx)	((void *) (ctx).sc_eip)
+#define GET_PC(ctx)	((uintptr_t) (ctx).sc_eip)
diff --git a/sysdeps/posix/profil.c b/sysdeps/posix/profil.c
index 838c36d060..4b8fd9caf1 100644
--- a/sysdeps/posix/profil.c
+++ b/sysdeps/posix/profil.c
@@ -21,6 +21,7 @@ 
 #include <errno.h>
 #include <signal.h>
 #include <sys/time.h>
+#include <stdint.h>
 #include <libc-internal.h>
 #include <sigsetops.h>
 
@@ -36,9 +37,9 @@  static size_t pc_offset;
 static u_int pc_scale;
 
 static inline void
-profil_count (void *pc)
+profil_count (uintptr_t pc)
 {
-  size_t i = (pc - pc_offset - (void *) 0) / 2;
+  size_t i = (pc - pc_offset) / 2;
 
   if (sizeof (unsigned long long int) > sizeof (size_t))
     i = (unsigned long long int) i * pc_scale / 65536;
@@ -71,6 +72,10 @@  __profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 # define oact_ptr &oact
 # define otimer_ptr &otimer
 
+# ifdef SA_SIGINFO
+  oact.sa_flags |= SA_SIGINFO;
+# endif
+
   if (sample_buffer == NULL)
     {
       /* Disable profiling.  */
@@ -104,8 +109,14 @@  __profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
   pc_offset = offset;
   pc_scale = scale;
 
-  act.sa_handler = (sighandler_t) &__profil_counter;
-  act.sa_flags = SA_RESTART;
+#ifdef SA_SIGINFO
+  act.sa_sigaction = __profil_counter;
+  act.sa_flags = SA_SIGINFO;
+#else
+  act.sa_handler = __profil_counter;
+  act.sa_flags = 0;
+#endif
+  act.sa_flags |= SA_RESTART;
   __sigfillset (&act.sa_mask);
   if (__sigaction (SIGPROF, &act, oact_ptr) < 0)
     return -1;
diff --git a/sysdeps/posix/sprofil.c b/sysdeps/posix/sprofil.c
index 3f76bf5174..a9d4a7f3b4 100644
--- a/sysdeps/posix/sprofil.c
+++ b/sysdeps/posix/sprofil.c
@@ -105,10 +105,10 @@  index_to_pc (unsigned long int n, size_t offset, unsigned int scale,
 }
 
 static void
-profil_count (void *pcp, int prof_uint)
+profil_count (uintptr_t pcp, int prof_uint)
 {
   struct region *region, *r = prof_info.last;
-  size_t lo, hi, mid, pc = (unsigned long int) pcp;
+  size_t lo, hi, mid, pc = pcp;
   unsigned long int i;
 
   /* Fast path: pc is in same region as before.  */
@@ -165,13 +165,13 @@  profil_count (void *pcp, int prof_uint)
 }
 
 static inline void
-profil_count_ushort (void *pcp)
+profil_count_ushort (uintptr_t pcp)
 {
   profil_count (pcp, 0);
 }
 
 static inline void
-profil_count_uint (void *pcp)
+profil_count_uint (uintptr_t pcp)
 {
   profil_count (pcp, 1);
 }
@@ -334,11 +334,18 @@  __sprofil (struct prof *profp, int profcnt, struct timeval *tvp,
   prof_info.last = prof_info.region;
 
   /* Install SIGPROF handler.  */
-  if (flags & PROF_UINT)
-    act.sa_handler = (sighandler_t) &__profil_counter_uint;
-  else
-    act.sa_handler = (sighandler_t) &__profil_counter_ushort;
-  act.sa_flags = SA_RESTART;
+#ifdef SA_SIGINFO
+  act.sa_sigaction= flags & PROF_UINT
+		    ? __profil_counter_uint
+		    : __profil_counter_ushort;
+  act.sa_flags = SA_SIGINFO;
+#else
+  act.sa_handler = flags & PROF_UINT
+		   ? (sighandler_t) __profil_counter_uint
+		   : (sighandler_t) __profil_counter_ushort;
+  act.sa_flags = 0;
+#endif
+  act.sa_flags |= SA_RESTART;
   __sigfillset (&act.sa_mask);
   if (__sigaction (SIGPROF, &act, &prof_info.saved_action) < 0)
     return -1;
diff --git a/sysdeps/unix/sysv/linux/aarch64/profil-counter.h b/sysdeps/unix/sysv/linux/aarch64/profil-counter.h
deleted file mode 100644
index 4f8b6501c0..0000000000
--- a/sysdeps/unix/sysv/linux/aarch64/profil-counter.h
+++ /dev/null
@@ -1,20 +0,0 @@ 
-/* Copyright (C) 2009-2019 Free Software Foundation, Inc.
-
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-/* We can use the ix86 version.  */
-#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
diff --git a/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
index a0b0002c3d..788f16d124 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
@@ -19,17 +19,4 @@ 
 #include <stdint.h>
 #include <sys/ucontext.h>
 
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-#define GET_PC(ctx) ((void *) (uintptr_t) (ctx)->uc_mcontext.pc)
-
-/* There is no reliable way to get the sigcontext unless we use a
-   three-argument signal handler.  */
-#define __sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (__sigaction) (sig, act, oact); \
-})
-
-#define sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (sigaction) (sig, act, oact); \
-})
+#define GET_PC(ctx) ((uintptr_t)(((ucontext_t *) (ctx))->uc_mcontext.pc))
diff --git a/sysdeps/unix/sysv/linux/alpha/register-dump.h b/sysdeps/unix/sysv/linux/alpha/register-dump.h
index 9d55bc0fc5..45dafe0a1f 100644
--- a/sysdeps/unix/sysv/linux/alpha/register-dump.h
+++ b/sysdeps/unix/sysv/linux/alpha/register-dump.h
@@ -16,8 +16,10 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <stddef.h>
 #include <string.h>
+#include <ucontext.h>
+#include <sys/uio.h>
+#include <_itoa.h>
 
 /* We will print the register dump in this format:
 
@@ -48,109 +50,190 @@ 
    TA0: XXXXXXXXXXXXXXXX   TA1: XXXXXXXXXXXXXXXX   TA2: XXXXXXXXXXXXXXXX
 */
 
-#define NREGS (32+32+3)
-
-static const char __attribute__((aligned(8))) regnames[NREGS][8] =
-{
-  "    V0: ", "    T0: ", "    T1: ",
-  "    T2: ", "    T3: ", "    T4: ",
-  "    T5: ", "    T6: ", "    T7: ",
-  "    S0: ", "    S1: ", "    S2: ",
-  "    S3: ", "    S4: ", "    S5: ",
-  "    S6: ", "    A0: ", "    A1: ",
-  "    A2: ", "    A3: ", "    A4: ",
-  "    A5: ", "    T8: ", "    T9: ",
-  "   T10: ", "   T11: ", "    RA: ",
-  "   T12: ", "    AT: ", "    GP: ",
-  "    SP: ", "    PC: ",
-
-  "   FP0: ", "   FP1: ", "   FP2: ",
-  "   FP3: ", "   FP4: ", "   FP5: ",
-  "   FP6: ", "   FP7: ", "   FP8: ",
-  "   FP9: ", "  FP10: ", "  FP11: ",
-  "  FP12: ", "  FP13: ", "  FP14: ",
-  "  FP15: ", "  FP16: ", "  FP17: ",
-  "  FP18: ", "  FP19: ", "  FP20: ",
-  "  FP21: ", "  FP22: ", "  FP23: ",
-  "  FP24: ", "  FP25: ", "  FP26: ",
-  "  FP27: ", "  FP28: ", "  FP29: ",
-  "  FP30: ", "  FPCR: ",
-
-  "   TA0: ", "   TA1: ", "   TA2: "
-};
-
-#define O(FIELD, LF)  offsetof(struct sigcontext, FIELD) + LF
-
-static const int offsets[NREGS] =
+static void
+hexvalue (unsigned long int value, char *buf, size_t len)
 {
-  O(sc_regs[0], 0),  O(sc_regs[1], 0),  O(sc_regs[2], 1),
-  O(sc_regs[3], 0),  O(sc_regs[4], 0),  O(sc_regs[5], 1),
-  O(sc_regs[6], 0),  O(sc_regs[7], 0),  O(sc_regs[8], 1),
-  O(sc_regs[9], 0),  O(sc_regs[10], 0), O(sc_regs[11], 1),
-  O(sc_regs[12], 0), O(sc_regs[13], 0), O(sc_regs[14], 1),
-  O(sc_regs[15], 0), O(sc_regs[16], 0), O(sc_regs[17], 1),
-  O(sc_regs[18], 0), O(sc_regs[19], 0), O(sc_regs[20], 1),
-  O(sc_regs[21], 0), O(sc_regs[22], 0), O(sc_regs[23], 1),
-  O(sc_regs[24], 0), O(sc_regs[25], 0), O(sc_regs[26], 1),
-  O(sc_regs[27], 0), O(sc_regs[28], 0), O(sc_regs[29], 1),
-  O(sc_regs[30], 0), O(sc_pc, 2),
-
-  O(sc_fpregs[0], 0),  O(sc_fpregs[1], 0),  O(sc_fpregs[2], 1),
-  O(sc_fpregs[3], 0),  O(sc_fpregs[4], 0),  O(sc_fpregs[5], 1),
-  O(sc_fpregs[6], 0),  O(sc_fpregs[7], 0),  O(sc_fpregs[8], 1),
-  O(sc_fpregs[9], 0),  O(sc_fpregs[10], 0), O(sc_fpregs[11], 1),
-  O(sc_fpregs[12], 0), O(sc_fpregs[13], 0), O(sc_fpregs[14], 1),
-  O(sc_fpregs[15], 0), O(sc_fpregs[16], 0), O(sc_fpregs[17], 1),
-  O(sc_fpregs[18], 0), O(sc_fpregs[19], 0), O(sc_fpregs[20], 1),
-  O(sc_fpregs[21], 0), O(sc_fpregs[22], 0), O(sc_fpregs[23], 1),
-  O(sc_fpregs[24], 0), O(sc_fpregs[25], 0), O(sc_fpregs[26], 1),
-  O(sc_fpregs[27], 0), O(sc_fpregs[28], 0), O(sc_fpregs[29], 1),
-  O(sc_fpregs[30], 0), O(sc_fpcr, 2),
-
-  O(sc_traparg_a0, 0),  O(sc_traparg_a1, 0),  O(sc_traparg_a2, 1)
-};
-
-#undef O
+  char *cp = _itoa_word (value, buf + len, 16, 0);
+  while (cp > buf)
+    *--cp = '0';
+}
 
 static void
-register_dump (int fd, struct sigcontext *ctx)
+register_dump (int fd, struct ucontext_t *ctx)
 {
-  char buf[NREGS*(8+16) + 25 + 80];
-  char *p = buf;
-  size_t i;
-
-  p = stpcpy (p, "Register dump:\n\n");
-
-  for (i = 0; i < NREGS; ++i)
-    {
-      int this_offset, this_lf;
-      unsigned long val;
-      signed long j;
-
-      this_offset = offsets[i];
-      this_lf = this_offset & 7;
-
-      val = *(unsigned long *)(((size_t)ctx + this_offset) & -8);
-
-      memcpy (p, regnames[i], 8);
-      p += 8;
-
-      for (j = 60; j >= 0; j -= 4)
-	{
-	  unsigned long x = (val >> j) & 15;
-	  x += x < 10 ? '0' : 'a' - 10;
-	  *p++ = x;
-	}
-
-      if (this_lf > 0)
-	{
-	  if (this_lf > 1)
-	    *p++ = '\n';
-	  *p++ = '\n';
-	}
-    }
-
-  write (fd, buf, p - buf);
+  struct iovec iov[31 * 2 + 2    /* REGS + PC.  */
+                   + 31 * 2 + 2  /* FREGS + FPCR.  */
+                   + (3 * 2)     /* TA0, TA1, TA3.  */
+                   + 1           /* '\n'.  */];
+  size_t nr = 0;
+
+#define ADD_STRING(str) \
+  iov[nr].iov_base = (char *) str;					      \
+  iov[nr].iov_len = strlen (str);					      \
+  ++nr
+#define ADD_MEM(str, len) \
+  iov[nr].iov_base = str;						      \
+  iov[nr].iov_len = len;						      \
+  ++nr
+
+  char regs[31][16];
+  char pc[16];
+  for (int i = 0; i < 31; i++)
+    hexvalue (ctx->uc_mcontext.sc_regs[i], regs[i], 16);
+  hexvalue (ctx->uc_mcontext.sc_pc, pc, 16);
+
+  /* Generate the output.  */
+  ADD_STRING ("Register dump:\n\n    V0: ");
+  ADD_MEM (regs[0], 16);
+  ADD_STRING ("    T0: ");
+  ADD_MEM (regs[1], 16);
+  ADD_STRING ("    T1: ");
+  ADD_MEM (regs[2], 16);
+  ADD_STRING ("\n    T2: ");
+  ADD_MEM (regs[3], 16);
+  ADD_STRING ("    T3: ");
+  ADD_MEM (regs[4], 16);
+  ADD_STRING ("    T4: ");
+  ADD_MEM (regs[5], 16);
+  ADD_STRING ("\n    T5: ");
+  ADD_MEM (regs[6], 16);
+  ADD_STRING ("    T6: ");
+  ADD_MEM (regs[7], 16);
+  ADD_STRING ("    T7: ");
+  ADD_MEM (regs[8], 16);
+  ADD_STRING ("\n    S0: ");
+  ADD_MEM (regs[9], 16);
+  ADD_STRING ("    S1: ");
+  ADD_MEM (regs[10], 16);
+  ADD_STRING ("    S2: ");
+  ADD_MEM (regs[11], 16);
+  ADD_STRING ("\n    S3: ");
+  ADD_MEM (regs[12], 16);
+  ADD_STRING ("    S4: ");
+  ADD_MEM (regs[13], 16);
+  ADD_STRING ("    S5: ");
+  ADD_MEM (regs[14], 16);
+  ADD_STRING ("\n    S6: ");
+  ADD_MEM (regs[15], 16);
+  ADD_STRING ("    A0: ");
+  ADD_MEM (regs[16], 16);
+  ADD_STRING ("    A1: ");
+  ADD_MEM (regs[17], 16);
+  ADD_STRING ("\n    A2: ");
+  ADD_MEM (regs[18], 16);
+  ADD_STRING ("    A3: ");
+  ADD_MEM (regs[19], 16);
+  ADD_STRING ("    A4: ");
+  ADD_MEM (regs[20], 16);
+  ADD_STRING ("\n    A5: ");
+  ADD_MEM (regs[21], 16);
+  ADD_STRING ("    T8: ");
+  ADD_MEM (regs[22], 16);
+  ADD_STRING ("    T9: ");
+  ADD_MEM (regs[23], 16);
+  ADD_STRING ("\n   T10: ");
+  ADD_MEM (regs[24], 16);
+  ADD_STRING ("   T11: ");
+  ADD_MEM (regs[25], 16);
+  ADD_STRING ("    RA: ");
+  ADD_MEM (regs[26], 16);
+  ADD_STRING ("\n   T12: ");
+  ADD_MEM (regs[27], 16);
+  ADD_STRING ("    AT: ");
+  ADD_MEM (regs[28], 16);
+  ADD_STRING ("    GP: ");
+  ADD_MEM (regs[29], 16);
+  ADD_STRING ("\n    SP: ");
+  ADD_MEM (regs[30], 16);
+  ADD_STRING ("    PC: ");
+  ADD_MEM (pc, 16);
+
+  char fpregs[31][16];
+  char fpcr[16];
+  for (int i = 0; i < 31; i++)
+    hexvalue (ctx->uc_mcontext.sc_fpregs[i], fpregs[i], 16);
+  hexvalue (ctx->uc_mcontext.sc_fpcr, fpcr, 16);
+
+  ADD_STRING ("\n\n   FP0: ");
+  ADD_MEM (fpregs[0], 16);
+  ADD_STRING ("   FP1: ");
+  ADD_MEM (fpregs[1], 16);
+  ADD_STRING ("   FP2: ");
+  ADD_MEM (fpregs[2], 16);
+  ADD_STRING ("\n   FP3: ");
+  ADD_MEM (fpregs[3], 16);
+  ADD_STRING ("   FP4: ");
+  ADD_MEM (fpregs[4], 16);
+  ADD_STRING ("   FP5: ");
+  ADD_MEM (fpregs[5], 16);
+  ADD_STRING ("\n   FP6: ");
+  ADD_MEM (fpregs[6], 16);
+  ADD_STRING ("   FP7: ");
+  ADD_MEM (fpregs[7], 16);
+  ADD_STRING ("   FP8: ");
+  ADD_MEM (fpregs[8], 16);
+  ADD_STRING ("\n   FP9: ");
+  ADD_MEM (fpregs[9], 16);
+  ADD_STRING ("  FP10: ");
+  ADD_MEM (fpregs[10], 16);
+  ADD_STRING ("  FP11: ");
+  ADD_MEM (fpregs[11], 16);
+  ADD_STRING ("\n  FP12: ");
+  ADD_MEM (fpregs[12], 16);
+  ADD_STRING ("  FP13: ");
+  ADD_MEM (fpregs[13], 16);
+  ADD_STRING ("  FP14: ");
+  ADD_MEM (fpregs[14], 16);
+  ADD_STRING ("\n  FP15: ");
+  ADD_MEM (fpregs[15], 16);
+  ADD_STRING ("  FP16: ");
+  ADD_MEM (fpregs[16], 16);
+  ADD_STRING ("  FP17: ");
+  ADD_MEM (fpregs[17], 16);
+  ADD_STRING ("\n  FP18: ");
+  ADD_MEM (fpregs[18], 16);
+  ADD_STRING ("  FP19: ");
+  ADD_MEM (fpregs[19], 16);
+  ADD_STRING ("  FP20: ");
+  ADD_MEM (fpregs[20], 16);
+  ADD_STRING ("\n  FP21: ");
+  ADD_MEM (fpregs[21], 16);
+  ADD_STRING ("  FP22: ");
+  ADD_MEM (fpregs[22], 16);
+  ADD_STRING ("  FP23: ");
+  ADD_MEM (fpregs[23], 16);
+  ADD_STRING ("\n  FP24: ");
+  ADD_MEM (fpregs[24], 16);
+  ADD_STRING ("  FP25: ");
+  ADD_MEM (fpregs[25], 16);
+  ADD_STRING ("  FP26: ");
+  ADD_MEM (fpregs[26], 16);
+  ADD_STRING ("\n  FP27: ");
+  ADD_MEM (fpregs[27], 16);
+  ADD_STRING ("  FP28: ");
+  ADD_MEM (fpregs[28], 16);
+  ADD_STRING ("  FP29: ");
+  ADD_MEM (fpregs[29], 16);
+  ADD_STRING ("\n  FP30: ");
+  ADD_MEM (fpregs[30], 16);
+  ADD_STRING ("  FPCR: ");
+  ADD_MEM (fpcr, 16);
+
+  char traparg[3][16];
+  hexvalue (ctx->uc_mcontext.sc_traparg_a0, traparg[0], 16);
+  hexvalue (ctx->uc_mcontext.sc_traparg_a1, traparg[1], 16);
+  hexvalue (ctx->uc_mcontext.sc_traparg_a2, traparg[2], 16);
+  ADD_STRING ("\n\n   TA0: ");
+  ADD_MEM (traparg[0], 16);
+  ADD_STRING ("   TA1: ");
+  ADD_MEM (traparg[1], 16);
+  ADD_STRING ("   TA2: ");
+  ADD_MEM (traparg[2], 16);
+
+  ADD_STRING ("\n");
+
+  /* Write the stuff out.  */
+  writev (fd, iov, nr);
 }
 
 #define REGISTER_DUMP register_dump (fd, ctx)
diff --git a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
index 45d06f9a12..2a2b71077d 100644
--- a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
@@ -15,5 +15,7 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define SIGCONTEXT int _code, struct sigcontext *
-#define GET_PC(ctx)	((void *) (ctx)->sc_pc)
+#include <stdint.h>
+#include <sys/ucontext.h>
+
+#define GET_PC(ctx) ((uintptr_t)(((ucontext_t *) (ctx))->uc_mcontext.sc_pc))
diff --git a/sysdeps/unix/sysv/linux/arm/profil-counter.h b/sysdeps/unix/sysv/linux/arm/profil-counter.h
index 494c2172b6..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]))