[v2,3/4] Refactor sigcontextinfo.h
diff mbox series

Message ID 20190815211843.22799-3-adhemerval.zanella@linaro.org
State New
Headers show
Series
  • [1/4] Add RTLD_SINGLE_THREAD_P on generic single-thread.h
Related show

Commit Message

Adhemerval Zanella Aug. 15, 2019, 9:18 p.m. UTC
Changes from previous version:

  - Add a testcase for sigcontext_get_pc (Florian Weimer suggestion and
    initial implementation).

  - Fix some comment wording and trailing whitespace.

---

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 a inline function, sigcontext_get_pc
which 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 struct sigcontextt
     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.

	Adhemerval Zanella  <adhemerval.zanella@linaro.org>
	Florian Weimer  <fweimer@redhat.com>

	* 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): Replace with
	sigcontext_get_pc.
	* 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.
	(sigcontext_get_pc): New function.
	* 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.
	* sysdeps/unix/sysv/linux/Makefile (tests-internal): Add
	tst-sigcontextinfo-get_pc.
	* sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c: New file.
	(CFLAGS-tst-sigcontextinfo-get_pc.c): New rule.
---
 debug/segfault.c                              |  16 +-
 sysdeps/generic/profil-counter.h              |   2 +-
 sysdeps/generic/sigcontextinfo.h              |  11 +-
 sysdeps/mach/hurd/i386/sigcontextinfo.h       |  11 +-
 sysdeps/posix/profil.c                        |  19 +-
 sysdeps/posix/sprofil.c                       |  25 +-
 sysdeps/unix/sysv/linux/Makefile              |   4 +-
 .../unix/sysv/linux/aarch64/profil-counter.h  |  20 --
 .../unix/sysv/linux/aarch64/sigcontextinfo.h  |  22 +-
 sysdeps/unix/sysv/linux/alpha/register-dump.h | 283 +++++++++++-------
 .../unix/sysv/linux/alpha/sigcontextinfo.h    |  15 +-
 sysdeps/unix/sysv/linux/arm/profil-counter.h  |   4 +-
 sysdeps/unix/sysv/linux/arm/sigcontextinfo.h  |  27 +-
 sysdeps/unix/sysv/linux/csky/profil-counter.h |  31 --
 sysdeps/unix/sysv/linux/csky/sigcontextinfo.h |  20 +-
 .../{profil-counter.h => sigcontextinfo.h}    |  16 +-
 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 |  12 +-
 sysdeps/unix/sysv/linux/ia64/profil-counter.h |  31 --
 sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h |  14 +-
 sysdeps/unix/sysv/linux/m68k/register-dump.h  | 117 ++++----
 sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h |  12 +-
 .../sysv/linux/microblaze/profil-counter.h    |   2 -
 .../sysv/linux/microblaze/sigcontextinfo.h    |  12 +-
 sysdeps/unix/sysv/linux/mips/profil-counter.h |   2 -
 sysdeps/unix/sysv/linux/mips/sigcontextinfo.h |  20 +-
 .../unix/sysv/linux/nios2/profil-counter.h    |   2 -
 .../unix/sysv/linux/nios2/sigcontextinfo.h    |  23 +-
 .../unix/sysv/linux/powerpc/profil-counter.h  |   2 -
 .../unix/sysv/linux/powerpc/sigcontextinfo.h  |  16 +-
 .../sysv/linux/{x86_64 => }/profil-counter.h  |  13 +-
 .../unix/sysv/linux/riscv/profil-counter.h    |  31 --
 .../unix/sysv/linux/riscv/sigcontextinfo.h    |  12 +-
 .../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 |  16 +-
 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   |  11 +-
 .../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 |  40 ++-
 .../sysv/linux/sparc/sparc64/register-dump.h  |  42 ++-
 .../sysv/linux/sparc/sparc64/sigcontextinfo.h |  42 ++-
 .../sysv/linux/tst-sigcontextinfo-get_pc.c    |  81 +++++
 .../unix/sysv/linux/x86_64/sigcontextinfo.h   |  13 +-
 51 files changed, 927 insertions(+), 964 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} (76%)
 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 (66%)
 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
 create mode 100644 sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c

Comments

Adhemerval Zanella Aug. 19, 2019, 8:31 p.m. UTC | #1
Florian, 

Do you have any extra consideration about this patch? I will like to push
to send a new bz12683 fix set.

On 15/08/2019 18:18, Adhemerval Zanella wrote:
> Changes from previous version:
> 
>   - Add a testcase for sigcontext_get_pc (Florian Weimer suggestion and
>     initial implementation).
> 
>   - Fix some comment wording and trailing whitespace.
> 
> ---
> 
> 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 a inline function, sigcontext_get_pc
> which 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 struct sigcontextt
>      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.
> 
> 	Adhemerval Zanella  <adhemerval.zanella@linaro.org>
> 	Florian Weimer  <fweimer@redhat.com>
> 
> 	* 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): Replace with
> 	sigcontext_get_pc.
> 	* 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.
> 	(sigcontext_get_pc): New function.
> 	* 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.
> 	* sysdeps/unix/sysv/linux/Makefile (tests-internal): Add
> 	tst-sigcontextinfo-get_pc.
> 	* sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c: New file.
> 	(CFLAGS-tst-sigcontextinfo-get_pc.c): New rule.
> ---
>  debug/segfault.c                              |  16 +-
>  sysdeps/generic/profil-counter.h              |   2 +-
>  sysdeps/generic/sigcontextinfo.h              |  11 +-
>  sysdeps/mach/hurd/i386/sigcontextinfo.h       |  11 +-
>  sysdeps/posix/profil.c                        |  19 +-
>  sysdeps/posix/sprofil.c                       |  25 +-
>  sysdeps/unix/sysv/linux/Makefile              |   4 +-
>  .../unix/sysv/linux/aarch64/profil-counter.h  |  20 --
>  .../unix/sysv/linux/aarch64/sigcontextinfo.h  |  22 +-
>  sysdeps/unix/sysv/linux/alpha/register-dump.h | 283 +++++++++++-------
>  .../unix/sysv/linux/alpha/sigcontextinfo.h    |  15 +-
>  sysdeps/unix/sysv/linux/arm/profil-counter.h  |   4 +-
>  sysdeps/unix/sysv/linux/arm/sigcontextinfo.h  |  27 +-
>  sysdeps/unix/sysv/linux/csky/profil-counter.h |  31 --
>  sysdeps/unix/sysv/linux/csky/sigcontextinfo.h |  20 +-
>  .../{profil-counter.h => sigcontextinfo.h}    |  16 +-
>  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 |  12 +-
>  sysdeps/unix/sysv/linux/ia64/profil-counter.h |  31 --
>  sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h |  14 +-
>  sysdeps/unix/sysv/linux/m68k/register-dump.h  | 117 ++++----
>  sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h |  12 +-
>  .../sysv/linux/microblaze/profil-counter.h    |   2 -
>  .../sysv/linux/microblaze/sigcontextinfo.h    |  12 +-
>  sysdeps/unix/sysv/linux/mips/profil-counter.h |   2 -
>  sysdeps/unix/sysv/linux/mips/sigcontextinfo.h |  20 +-
>  .../unix/sysv/linux/nios2/profil-counter.h    |   2 -
>  .../unix/sysv/linux/nios2/sigcontextinfo.h    |  23 +-
>  .../unix/sysv/linux/powerpc/profil-counter.h  |   2 -
>  .../unix/sysv/linux/powerpc/sigcontextinfo.h  |  16 +-
>  .../sysv/linux/{x86_64 => }/profil-counter.h  |  13 +-
>  .../unix/sysv/linux/riscv/profil-counter.h    |  31 --
>  .../unix/sysv/linux/riscv/sigcontextinfo.h    |  12 +-
>  .../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 |  16 +-
>  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   |  11 +-
>  .../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 |  40 ++-
>  .../sysv/linux/sparc/sparc64/register-dump.h  |  42 ++-
>  .../sysv/linux/sparc/sparc64/sigcontextinfo.h |  42 ++-
>  .../sysv/linux/tst-sigcontextinfo-get_pc.c    |  81 +++++
>  .../unix/sysv/linux/x86_64/sigcontextinfo.h   |  13 +-
>  51 files changed, 927 insertions(+), 964 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} (76%)
>  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 (66%)
>  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
>  create mode 100644 sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c
> 
> diff --git a/debug/segfault.c b/debug/segfault.c
> index bd1008d9af..cd3bfab55c 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>
>  
> @@ -101,7 +105,7 @@ catch_segfault (int signal, SIGCONTEXT ctx)
>       Normally it will be found at arr[2], but it might appear later
>       if there were some signal handler wrappers.  Allow a few bytes
>       difference to cope with as many arches as possible.  */
> -  pc = (uintptr_t) GET_PC (ctx);
> +  pc = sigcontext_get_pc (ctx);
>    for (i = 0; i < cnt; ++i)
>      if ((uintptr_t) arr[i] >= pc - 16 && (uintptr_t) arr[i] <= pc + 16)
>        break;
> @@ -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..92c0328fb7 100644
> --- a/sysdeps/generic/sigcontextinfo.h
> +++ b/sysdeps/generic/sigcontextinfo.h
> @@ -16,6 +16,15 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
>  /* In general we cannot provide any information.  */
>  #define SIGCONTEXT struct sigcontext *
> -#define GET_PC(ctx)	((void *) 0)
> +static inline uintptr_t
> +sigcontext_get_pc (const struct sigcontext *ctx)
> +{
> +  return 0;
> +}
> +
> +#endif
> diff --git a/sysdeps/mach/hurd/i386/sigcontextinfo.h b/sysdeps/mach/hurd/i386/sigcontextinfo.h
> index 65bf12976d..3d9be4e2a6 100644
> --- a/sysdeps/mach/hurd/i386/sigcontextinfo.h
> +++ b/sysdeps/mach/hurd/i386/sigcontextinfo.h
> @@ -15,5 +15,14 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
>  #define SIGCONTEXT struct sigcontext
> -#define GET_PC(ctx)	((void *) (ctx).sc_eip)
> +static inline uintptr_t
> +sigcontext_get_pc (struct sigcontext ctx)
> +{
> +  return ctx.sc_eip;
> +}
> +
> +#endif
> 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/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index 1ab6bcbfc8..9b4fbfac3b 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -55,7 +55,9 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
>  	 test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
>  	 tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
>  	 tst-tgkill
> -tests-internal += tst-ofdlocks-compat
> +tests-internal += tst-ofdlocks-compat tst-sigcontextinfo-get_pc
> +
> +CFLAGS-tst-sigcontextinfo-get_pc.c = -fasynchronous-unwind-tables
>  
>  # Generate the list of SYS_* macros for the system calls (__NR_*
>  # macros).  The file syscall-names.list contains all possible system
> 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..e001e7c193 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
> @@ -16,20 +16,16 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
>  #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); \
> -})
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +  return ctx->uc_mcontext.pc;
> +}
>  
> -#define sigaction(sig, act, oact) ({ \
> -  (act)->sa_flags |= SA_SIGINFO; \
> -  (sigaction) (sig, act, oact); \
> -})
> +#endif
> 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..6147ba5f52 100644
> --- a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
> @@ -15,5 +15,16 @@
>     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)
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
> +#include <stdint.h>
> +#include <sys/ucontext.h>
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +  return ctx->uc_mcontext.sc_pc;
> +}
> +
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/arm/profil-counter.h b/sysdeps/unix/sysv/linux/arm/profil-counter.h
> index 494c2172b6..040c7aa59a 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 (sigcontext_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..d16ce06c3d 100644
> --- a/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h
> @@ -16,24 +16,13 @@
>     License along with the GNU C Library.  If not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> -#include <sys/ucontext.h>
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
>  
> -#define SIGCONTEXT siginfo_t *_si, ucontext_t *
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +  return ctx->uc_mcontext.arm_pc;
> +}
>  
> -/* 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); \
> -})
> +#endif
> 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..c5a775ccff 100644
> --- a/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
> @@ -16,17 +16,13 @@
>     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)
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
>  
> -/* 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); \
> -})
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +  return ctx->uc_mcontext.__gregs.__pc;
> +}
>  
> -#define sigaction(sig, act, oact) ({ \
> -  (act)->sa_flags |= SA_SIGINFO; \
> -  (sigaction) (sig, act, oact); \
> -})
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/hppa/profil-counter.h b/sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h
> similarity index 76%
> rename from sysdeps/unix/sysv/linux/hppa/profil-counter.h
> rename to sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h
> index bea7611465..4089d17855 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,15 @@
>     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)
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
> +#include <sys/ucontext.h>
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
>  {
> -  unsigned long ip = uctx->uc_mcontext.sc_iaoq[0] & ~0x3;
> -  profil_count ((void *) ip);
> +  return ctx->uc_mcontext.sc_iaoq[0] & ~0x3;
>  }
> +
> +#endif
> 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..d0f23f5f0e 100644
> --- a/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
> @@ -16,5 +16,13 @@
>     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)
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> + return ctx->uc_mcontext.gregs[REG_EIP];
> +}
> +
> +#endif
> 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..7e56c239bb 100644
> --- a/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
> @@ -15,5 +15,15 @@
>     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)
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
> +/* Unlike other architectures, ia64 passes 'struct sigcontext' pointer as
> +   the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
> +static inline uintptr_t
> +sigcontext_get_pc (const struct sigcontext *ctx)
> +{
> +  return ctx->sc_ip;
> +}
> +
> +#endif
> 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..b98fd28c11 100644
> --- a/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h
> @@ -16,5 +16,13 @@
>     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)
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> + return ctx->uc_mcontext.gregs[R_PC];
> +}
> +
> +#endif
> 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..7978fc3268 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h
> @@ -16,5 +16,13 @@
>     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)
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> + return ctx->uc_mcontext.regs.pc;
> +}
> +
> +#endif
> 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..89d831f6d9 100644
> --- a/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h
> @@ -16,17 +16,13 @@
>     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)
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> + return ctx->uc_mcontext.pc;
> +}
>  
>  #endif
> 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..f388dcc35c 100644
> --- a/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h
> @@ -16,20 +16,13 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> -#include <sys/ucontext.h>
> -#include "kernel-features.h"
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
>  
> -#define SIGCONTEXT siginfo_t *_si, ucontext_t *
> -#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.regs[27])
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> + return 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); \
> -})
> +#endif
> 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..3cfba22c74 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
> @@ -15,7 +15,19 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
>  #include <signal.h>
>  
> -#define SIGCONTEXT struct sigcontext *
> -#define GET_PC(ctx)	((void *)((ctx)->regs->nip))
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +#ifdef __powerpc64__
> +  return ctx->uc_mcontext.gp_regs[PT_NIP];
> +#else
> +  return ctx->uc_mcontext.uc_regs->gregs[PT_NIP];
> +#endif
> +}
> +
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/x86_64/profil-counter.h b/sysdeps/unix/sysv/linux/profil-counter.h
> similarity index 66%
> rename from sysdeps/unix/sysv/linux/x86_64/profil-counter.h
> rename to sysdeps/unix/sysv/linux/profil-counter.h
> index 48a266e3ef..50af90cb13 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 (sigcontext_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..f88b86dd86 100644
> --- a/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
> @@ -16,7 +16,15 @@
>     License along with the GNU C Library.  If not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
>  #include <sys/ucontext.h>
>  
> -#define SIGCONTEXT siginfo_t *_si, ucontext_t *
> -#define GET_PC(ctx)	((void *) ctx->uc_mcontext.__gregs[REG_PC])
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> + return ctx->uc_mcontext.__gregs[REG_PC];
> +}
> +
> +#endif
> 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..576dc6126b 100644
> --- a/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
> @@ -16,7 +16,19 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
> +
>  #include <signal.h>
>  
> -#define SIGCONTEXT struct sigcontext *
> -#define GET_PC(ctx)	((void *)((ctx)->sregs->regs.psw.addr))
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +#ifdef __s390x__
> + return ctx->uc_mcontext.psw.addr;
> +#else
> + return ctx->uc_mcontext.psw.addr & 0x7FFFFFFF;
> +#endif
> +}
> +
> +#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..29d75b0cce 100644
> --- a/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
> @@ -16,6 +16,13 @@
>     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
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
>  
> -#define GET_PC(ctx)	((void *) ctx.sc_pc)
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +  return ctx->uc_mcontext.pc;
> +}
> +
> +#endif
> 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..dd21f273d6 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
> @@ -16,5 +16,41 @@
>     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 sparc32 kernel signal frame for SA_SIGINFO is defined as:
> +
> +  struct rt_signal_frame32
> +    {
> +      struct sparc_stackf32 ss;
> +      compat_siginfo_t info;
> +      struct pt_regs32 regs;          <- void *ctx
> +      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)));
> +
> +  Unlike other architectures, sparc32 passes pt_regs32 REGS pointer as
> +  the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
> +
> +struct pt_regs32
> +{
> +  unsigned int psr;
> +  unsigned int pc;
> +  unsigned int npc;
> +  unsigned int y;
> +  unsigned int u_regs[16];
> +};
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const struct pt_regs32 *ctx)
> +{
> +  return 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..23ff36453a 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';
>  }
>  
> +/* The sparc64 kernel signal frame for SA_SIGINFO is defined 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;
> +     };
> +
> +  Unlike other architectures, sparc32 passes pt_regs32 REGS pointers as
> +  the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
> +
>  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..adc84d3ce4 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
> @@ -16,8 +16,46 @@
>     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 sparc64 kernel signal frame for SA_SIGINFO is defined 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;
> +     };
> +
> +  Unlike other architectures, sparc64 passe the siginfo_t INFO pointer
> +  as the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
> +
>  #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 int u_regs[16];
> + unsigned long int tstate;
> + unsigned long int tpc;
> + unsigned long int tnpc;
> + unsigned int y;
> + unsigned int magic;
> +};
> +
> +static inline uintptr_t
> +sigcontext_get_pc (const siginfo_t *ctx)
> +{
> +  struct pt_regs *regs = (struct pt_regs*) ((siginfo_t *)(ctx) + 1);
> +  return regs->tpc;
> +}
> +
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c
> new file mode 100644
> index 0000000000..60a4c6b8f4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c
> @@ -0,0 +1,81 @@
> +/* Test that the GET_PC macro is consistent with the unwinder.
> +   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
> +   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; see the file COPYING.LIB.  If
> +   not, see <http://www.gnu.org/licenses/>.  */
> +
> +/* This test searches for the value of the GET_PC macro in the
> +   addresses obtained from the backtrace function.  */
> +
> +#include <array_length.h>
> +#include <execinfo.h>
> +#include <inttypes.h>
> +#include <signal.h>
> +#include <stdbool.h>
> +#include <stdio.h>
> +#include <support/check.h>
> +#include <support/xsignal.h>
> +
> +/* This file defines macros to access the content of the sigcontext element
> +   passed up by the signal handler.  */
> +#include <sigcontextinfo.h>
> +
> +static bool handler_called;
> +
> +static void
> +handler (int signal, siginfo_t *info, void *ctx)
> +{
> +  TEST_COMPARE (signal, SIGUSR1);
> +
> +  uintptr_t pc = sigcontext_get_pc (ctx);
> +  printf ("info: address in signal handler: 0x%" PRIxPTR "\n", pc);
> +
> +  void *callstack[10];
> +  int callstack_count = backtrace (callstack, array_length (callstack));
> +  TEST_VERIFY_EXIT (callstack_count > 0);
> +  TEST_VERIFY_EXIT (callstack_count <= array_length (callstack));
> +  bool found = false;
> +  for (int i = 0; i < callstack_count; ++i)
> +    {
> +      const char *marker;
> +      if ((uintptr_t) callstack[i] == pc)
> +        {
> +          found = true;
> +          marker = " *";
> +        }
> +      else
> +        marker = "";
> +      printf ("info: call stack entry %d: 0x%" PRIxPTR "%s\n",
> +              i, (uintptr_t) callstack[i], marker);
> +    }
> +  TEST_VERIFY (found);
> +  handler_called = true;
> +}
> +
> +static int
> +do_test (void)
> +{
> +  struct sigaction sa =
> +    {
> +     .sa_sigaction = &handler,
> +     .sa_flags = SA_SIGINFO
> +    };
> +  xsigaction (SIGUSR1, &sa, NULL);
> +  raise (SIGUSR1);
> +  TEST_VERIFY (handler_called);
> +  return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
> index 630f3992eb..056a42e13d 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
> +++ b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
> @@ -15,8 +15,13 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> -#include <stdint.h>
> +#ifndef _SIGCONTEXTINFO_H
> +#define _SIGCONTEXTINFO_H
>  
> -#define SIGCONTEXT siginfo_t *_si, ucontext_t *
> -#define GET_PC(ctx)	\
> -  ((void *) (uintptr_t) (ctx)->uc_mcontext.gregs[REG_RIP])
> +static inline uintptr_t
> +sigcontext_get_pc (const ucontext_t *ctx)
> +{
> +  return ctx->uc_mcontext.gregs[REG_RIP];
> +}
> +
> +#endif
>
Florian Weimer Aug. 20, 2019, 11:47 a.m. UTC | #2
* Adhemerval Zanella:

> 	* sysdeps/generic/profil-counter.h (__profil_counter): Cast to
> 	uintptr_t.
> 	(USE_SA_SIGINFO): New define.
> 	* sysdeps/generic/sigcontextinfo.h (GET_PC): Replace with
> 	sigcontext_get_pc.
> 	* 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.

USE_SA_SIGINFO does not seem to be present in the patch.

Thanks,
Florian
Florian Weimer Aug. 20, 2019, 11:51 a.m. UTC | #3
* Adhemerval Zanella:

> 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

> @@ -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
> +

I do not understand the purpose of this change.

Thanks,
Florian
Florian Weimer Aug. 20, 2019, 12:11 p.m. UTC | #4
* Adhemerval Zanella:

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

f_pcr used three times in both cases looks like a cut-and-paste error.
If this is correct, it needs a comment.

I'm surprised that this does not need a softfloat conditional.  Is the
sense of the comment really correct?  Based on the code, the registers
are saved by the kernel in the softfloat case (the opposite sense)
because there is no code to overwrite it.

Thanks,
Florian
Adhemerval Zanella Aug. 20, 2019, 12:19 p.m. UTC | #5
On 20/08/2019 08:47, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> 	* sysdeps/generic/profil-counter.h (__profil_counter): Cast to
>> 	uintptr_t.
>> 	(USE_SA_SIGINFO): New define.
>> 	* sysdeps/generic/sigcontextinfo.h (GET_PC): Replace with
>> 	sigcontext_get_pc.
>> 	* 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.
> 
> USE_SA_SIGINFO does not seem to be present in the patch.

Ack, fixed locally.
Adhemerval Zanella Aug. 20, 2019, 12:20 p.m. UTC | #6
On 20/08/2019 08:51, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> 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
> 
>> @@ -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
>> +
> 
> I do not understand the purpose of this change.

This code is shared with Hurd and it does not support SA_SIGINFO handler
afaiu.
Florian Weimer Aug. 20, 2019, 12:33 p.m. UTC | #7
* Adhemerval Zanella:

> On 20/08/2019 08:51, Florian Weimer wrote:
>> * Adhemerval Zanella:
>> 
>>> 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
>> 
>>> @@ -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
>>> +
>> 
>> I do not understand the purpose of this change.
>
> This code is shared with Hurd and it does not support SA_SIGINFO
> handler afaiu.

Hurd indeed does not SA_SIGINFO.  I do not understand the update of
oact.

Thanks,
Florian
Adhemerval Zanella Aug. 20, 2019, 12:42 p.m. UTC | #8
On 20/08/2019 09:33, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 20/08/2019 08:51, Florian Weimer wrote:
>>> * Adhemerval Zanella:
>>>
>>>> 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
>>>
>>>> @@ -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
>>>> +
>>>
>>> I do not understand the purpose of this change.
>>
>> This code is shared with Hurd and it does not support SA_SIGINFO
>> handler afaiu.
> 
> Hurd indeed does not SA_SIGINFO.  I do not understand the update of
> oact.
> 

Right, it indeed wrong. I removed this locally.
Adhemerval Zanella Aug. 20, 2019, 1:35 p.m. UTC | #9
On 20/08/2019 09:11, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> 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
>>  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
> 
> f_pcr used three times in both cases looks like a cut-and-paste error.
> If this is correct, it needs a comment.

Good catch, in fact the second field should the f_psr and third f_fpiaddr
from m68k struct fpregset_t. 

> 
> I'm surprised that this does not need a softfloat conditional.  Is the
> sense of the comment really correct?  Based on the code, the registers
> are saved by the kernel in the softfloat case (the opposite sense)
> because there is no code to overwrite it.

In fact I think I got this wrong checking on kernel code.  The 
rt_save_fpu_state function on arch/m68k/kernel/signal.c already handles 
FPU_IS_EMU, so this snippet is really unnecessary.  I will remove it.
Florian Weimer Aug. 20, 2019, 5:19 p.m. UTC | #10
* Adhemerval Zanella:

> diff --git a/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c
> new file mode 100644
> index 0000000000..60a4c6b8f4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c

I think the test should be called tst-sigcontext_get_pc, to match the
inline function name.

> +/* This file defines macros to access the content of the sigcontext element
> +   passed up by the signal handler.  */
> +#include <sigcontextinfo.h>

The comment is outdated, maybe we should just drop it.

Thanks,
Florian
Adhemerval Zanella Aug. 20, 2019, 6:23 p.m. UTC | #11
On 20/08/2019 14:19, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> diff --git a/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c
>> new file mode 100644
>> index 0000000000..60a4c6b8f4
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c
> 
> I think the test should be called tst-sigcontext_get_pc, to match the
> inline function name.

Ack, I changed it locally.

> 
>> +/* This file defines macros to access the content of the sigcontext element
>> +   passed up by the signal handler.  */
>> +#include <sigcontextinfo.h>
> 
> The comment is outdated, maybe we should just drop it.

Ack, I changed it locally.

> 
> Thanks,
> Florian
>
Florian Weimer Aug. 21, 2019, 9:06 a.m. UTC | #12
* Adhemerval Zanella:

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

You should use “Unlike other architectures” here as well, and “passes”
“as the third argument”, as in
sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h.

There is also some trailing whitespace left in the patch.

I do not have further comments on v2 of the patch.

Thanks,
Florian

Patch
diff mbox series

diff --git a/debug/segfault.c b/debug/segfault.c
index bd1008d9af..cd3bfab55c 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>
 
@@ -101,7 +105,7 @@  catch_segfault (int signal, SIGCONTEXT ctx)
      Normally it will be found at arr[2], but it might appear later
      if there were some signal handler wrappers.  Allow a few bytes
      difference to cope with as many arches as possible.  */
-  pc = (uintptr_t) GET_PC (ctx);
+  pc = sigcontext_get_pc (ctx);
   for (i = 0; i < cnt; ++i)
     if ((uintptr_t) arr[i] >= pc - 16 && (uintptr_t) arr[i] <= pc + 16)
       break;
@@ -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..92c0328fb7 100644
--- a/sysdeps/generic/sigcontextinfo.h
+++ b/sysdeps/generic/sigcontextinfo.h
@@ -16,6 +16,15 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
 /* In general we cannot provide any information.  */
 #define SIGCONTEXT struct sigcontext *
-#define GET_PC(ctx)	((void *) 0)
+static inline uintptr_t
+sigcontext_get_pc (const struct sigcontext *ctx)
+{
+  return 0;
+}
+
+#endif
diff --git a/sysdeps/mach/hurd/i386/sigcontextinfo.h b/sysdeps/mach/hurd/i386/sigcontextinfo.h
index 65bf12976d..3d9be4e2a6 100644
--- a/sysdeps/mach/hurd/i386/sigcontextinfo.h
+++ b/sysdeps/mach/hurd/i386/sigcontextinfo.h
@@ -15,5 +15,14 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
 #define SIGCONTEXT struct sigcontext
-#define GET_PC(ctx)	((void *) (ctx).sc_eip)
+static inline uintptr_t
+sigcontext_get_pc (struct sigcontext ctx)
+{
+  return ctx.sc_eip;
+}
+
+#endif
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/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 1ab6bcbfc8..9b4fbfac3b 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -55,7 +55,9 @@  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
 	 tst-rlimit-infinity tst-ofdlocks tst-gettid tst-gettid-kill \
 	 tst-tgkill
-tests-internal += tst-ofdlocks-compat
+tests-internal += tst-ofdlocks-compat tst-sigcontextinfo-get_pc
+
+CFLAGS-tst-sigcontextinfo-get_pc.c = -fasynchronous-unwind-tables
 
 # Generate the list of SYS_* macros for the system calls (__NR_*
 # macros).  The file syscall-names.list contains all possible system
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..e001e7c193 100644
--- a/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h
@@ -16,20 +16,16 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
 #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); \
-})
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+  return ctx->uc_mcontext.pc;
+}
 
-#define sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (sigaction) (sig, act, oact); \
-})
+#endif
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..6147ba5f52 100644
--- a/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h
@@ -15,5 +15,16 @@ 
    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)
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+#include <stdint.h>
+#include <sys/ucontext.h>
+
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+  return ctx->uc_mcontext.sc_pc;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/arm/profil-counter.h b/sysdeps/unix/sysv/linux/arm/profil-counter.h
index 494c2172b6..040c7aa59a 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 (sigcontext_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..d16ce06c3d 100644
--- a/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h
@@ -16,24 +16,13 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sys/ucontext.h>
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
 
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+  return ctx->uc_mcontext.arm_pc;
+}
 
-/* 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); \
-})
+#endif
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..c5a775ccff 100644
--- a/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/csky/sigcontextinfo.h
@@ -16,17 +16,13 @@ 
    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)
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
 
-/* 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); \
-})
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+  return ctx->uc_mcontext.__gregs.__pc;
+}
 
-#define sigaction(sig, act, oact) ({ \
-  (act)->sa_flags |= SA_SIGINFO; \
-  (sigaction) (sig, act, oact); \
-})
+#endif
diff --git a/sysdeps/unix/sysv/linux/hppa/profil-counter.h b/sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h
similarity index 76%
rename from sysdeps/unix/sysv/linux/hppa/profil-counter.h
rename to sysdeps/unix/sysv/linux/hppa/sigcontextinfo.h
index bea7611465..4089d17855 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,15 @@ 
    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)
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+#include <sys/ucontext.h>
+
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
 {
-  unsigned long ip = uctx->uc_mcontext.sc_iaoq[0] & ~0x3;
-  profil_count ((void *) ip);
+  return ctx->uc_mcontext.sc_iaoq[0] & ~0x3;
 }
+
+#endif
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..d0f23f5f0e 100644
--- a/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h
@@ -16,5 +16,13 @@ 
    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)
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+ return ctx->uc_mcontext.gregs[REG_EIP];
+}
+
+#endif
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..7e56c239bb 100644
--- a/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/ia64/sigcontextinfo.h
@@ -15,5 +15,15 @@ 
    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)
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+/* Unlike other architectures, ia64 passes 'struct sigcontext' pointer as
+   the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
+static inline uintptr_t
+sigcontext_get_pc (const struct sigcontext *ctx)
+{
+  return ctx->sc_ip;
+}
+
+#endif
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..b98fd28c11 100644
--- a/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h
@@ -16,5 +16,13 @@ 
    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)
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+ return ctx->uc_mcontext.gregs[R_PC];
+}
+
+#endif
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..7978fc3268 100644
--- a/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h
@@ -16,5 +16,13 @@ 
    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)
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+ return ctx->uc_mcontext.regs.pc;
+}
+
+#endif
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..89d831f6d9 100644
--- a/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h
@@ -16,17 +16,13 @@ 
    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)
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+ return ctx->uc_mcontext.pc;
+}
 
 #endif
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..f388dcc35c 100644
--- a/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h
@@ -16,20 +16,13 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sys/ucontext.h>
-#include "kernel-features.h"
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
 
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-#define GET_PC(ctx) ((void *) (ctx)->uc_mcontext.regs[27])
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+ return 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); \
-})
+#endif
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..3cfba22c74 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h
@@ -15,7 +15,19 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
 #include <signal.h>
 
-#define SIGCONTEXT struct sigcontext *
-#define GET_PC(ctx)	((void *)((ctx)->regs->nip))
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+#ifdef __powerpc64__
+  return ctx->uc_mcontext.gp_regs[PT_NIP];
+#else
+  return ctx->uc_mcontext.uc_regs->gregs[PT_NIP];
+#endif
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/profil-counter.h b/sysdeps/unix/sysv/linux/profil-counter.h
similarity index 66%
rename from sysdeps/unix/sysv/linux/x86_64/profil-counter.h
rename to sysdeps/unix/sysv/linux/profil-counter.h
index 48a266e3ef..50af90cb13 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 (sigcontext_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..f88b86dd86 100644
--- a/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h
@@ -16,7 +16,15 @@ 
    License along with the GNU C Library.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
 #include <sys/ucontext.h>
 
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-#define GET_PC(ctx)	((void *) ctx->uc_mcontext.__gregs[REG_PC])
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+ return ctx->uc_mcontext.__gregs[REG_PC];
+}
+
+#endif
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..576dc6126b 100644
--- a/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h
@@ -16,7 +16,19 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
 #include <signal.h>
 
-#define SIGCONTEXT struct sigcontext *
-#define GET_PC(ctx)	((void *)((ctx)->sregs->regs.psw.addr))
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+#ifdef __s390x__
+ return ctx->uc_mcontext.psw.addr;
+#else
+ return ctx->uc_mcontext.psw.addr & 0x7FFFFFFF;
+#endif
+}
+
+#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..29d75b0cce 100644
--- a/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h
@@ -16,6 +16,13 @@ 
    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
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
 
-#define GET_PC(ctx)	((void *) ctx.sc_pc)
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+  return ctx->uc_mcontext.pc;
+}
+
+#endif
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..dd21f273d6 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigcontextinfo.h
@@ -16,5 +16,41 @@ 
    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 sparc32 kernel signal frame for SA_SIGINFO is defined as:
+
+  struct rt_signal_frame32
+    {
+      struct sparc_stackf32 ss;
+      compat_siginfo_t info;
+      struct pt_regs32 regs;          <- void *ctx
+      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)));
+
+  Unlike other architectures, sparc32 passes pt_regs32 REGS pointer as
+  the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
+
+struct pt_regs32
+{
+  unsigned int psr;
+  unsigned int pc;
+  unsigned int npc;
+  unsigned int y;
+  unsigned int u_regs[16];
+};
+
+static inline uintptr_t
+sigcontext_get_pc (const struct pt_regs32 *ctx)
+{
+  return 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..23ff36453a 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';
 }
 
+/* The sparc64 kernel signal frame for SA_SIGINFO is defined 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;
+     };
+
+  Unlike other architectures, sparc32 passes pt_regs32 REGS pointers as
+  the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
+
 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..adc84d3ce4 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigcontextinfo.h
@@ -16,8 +16,46 @@ 
    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 sparc64 kernel signal frame for SA_SIGINFO is defined 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;
+     };
+
+  Unlike other architectures, sparc64 passe the siginfo_t INFO pointer
+  as the third argument to a sa_sigaction handler with SA_SIGINFO enabled.  */
+
 #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 int u_regs[16];
+ unsigned long int tstate;
+ unsigned long int tpc;
+ unsigned long int tnpc;
+ unsigned int y;
+ unsigned int magic;
+};
+
+static inline uintptr_t
+sigcontext_get_pc (const siginfo_t *ctx)
+{
+  struct pt_regs *regs = (struct pt_regs*) ((siginfo_t *)(ctx) + 1);
+  return regs->tpc;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c
new file mode 100644
index 0000000000..60a4c6b8f4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-sigcontextinfo-get_pc.c
@@ -0,0 +1,81 @@ 
+/* Test that the GET_PC macro is consistent with the unwinder.
+   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
+   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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* This test searches for the value of the GET_PC macro in the
+   addresses obtained from the backtrace function.  */
+
+#include <array_length.h>
+#include <execinfo.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <support/xsignal.h>
+
+/* This file defines macros to access the content of the sigcontext element
+   passed up by the signal handler.  */
+#include <sigcontextinfo.h>
+
+static bool handler_called;
+
+static void
+handler (int signal, siginfo_t *info, void *ctx)
+{
+  TEST_COMPARE (signal, SIGUSR1);
+
+  uintptr_t pc = sigcontext_get_pc (ctx);
+  printf ("info: address in signal handler: 0x%" PRIxPTR "\n", pc);
+
+  void *callstack[10];
+  int callstack_count = backtrace (callstack, array_length (callstack));
+  TEST_VERIFY_EXIT (callstack_count > 0);
+  TEST_VERIFY_EXIT (callstack_count <= array_length (callstack));
+  bool found = false;
+  for (int i = 0; i < callstack_count; ++i)
+    {
+      const char *marker;
+      if ((uintptr_t) callstack[i] == pc)
+        {
+          found = true;
+          marker = " *";
+        }
+      else
+        marker = "";
+      printf ("info: call stack entry %d: 0x%" PRIxPTR "%s\n",
+              i, (uintptr_t) callstack[i], marker);
+    }
+  TEST_VERIFY (found);
+  handler_called = true;
+}
+
+static int
+do_test (void)
+{
+  struct sigaction sa =
+    {
+     .sa_sigaction = &handler,
+     .sa_flags = SA_SIGINFO
+    };
+  xsigaction (SIGUSR1, &sa, NULL);
+  raise (SIGUSR1);
+  TEST_VERIFY (handler_called);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
index 630f3992eb..056a42e13d 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h
@@ -15,8 +15,13 @@ 
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <stdint.h>
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
 
-#define SIGCONTEXT siginfo_t *_si, ucontext_t *
-#define GET_PC(ctx)	\
-  ((void *) (uintptr_t) (ctx)->uc_mcontext.gregs[REG_RIP])
+static inline uintptr_t
+sigcontext_get_pc (const ucontext_t *ctx)
+{
+  return ctx->uc_mcontext.gregs[REG_RIP];
+}
+
+#endif