[v2] libgo: Don't use pt_regs member in mcontext_t

Message ID 20220306185921.21496-1-soeren@soeren-tempel.net
State New
Headers
Series [v2] libgo: Don't use pt_regs member in mcontext_t |

Commit Message

Li, Pan2 via Gcc-patches March 6, 2022, 6:59 p.m. UTC
  From: Sören Tempel <soeren+git@soeren-tempel.net>

The .regs member is primarily intended to be used in conjunction with
ptrace. Since this code is not using ptrace, using .regs is a bad idea.
Furthermore, the code currently fails to compile on musl since the
pt_regs type (used by .regs) is in an incomplete type which has to be
completed by inclusion of the asm/ptrace.h Kernel header. Contrary to
glibc, this header is not indirectly included by musl through other
header files.

This patch fixes compilation of this code with musl libc by accessing
the register values via .gp_regs/.gregs (depending on 32-bit or 64-bit
PowerPC) instead of using .regs. For more details, see
https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591261.html

For the offsets in gp_regs refer to the Kernel asm/ptrace.h header.

This patch has been tested on Alpine Linux ppc64le (uses musl libc).

Signed-off-by: Sören Tempel <soeren@soeren-tempel.net>

ChangeLog:

	* libgo/runtime/go-signal.c (defined): Use .gp_regs/.gregs
	  to access ppc64/ppc32 registers.
	(dumpregs): Ditto.
---
Changes since v1: Use .gp_regs/.gregs instead of .regs based on
feedback by Rich Felker, thereby avoiding the need to include
asm/ptrace.h for struct pt_regs.

 libgo/runtime/go-signal.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)
  

Comments

Rich Felker March 6, 2022, 9:21 p.m. UTC | #1
On Sun, Mar 06, 2022 at 07:59:24PM +0100, soeren@soeren-tempel.net wrote:
> From: Sören Tempel <soeren+git@soeren-tempel.net>
> 
> The .regs member is primarily intended to be used in conjunction with
> ptrace. Since this code is not using ptrace, using .regs is a bad idea.
> Furthermore, the code currently fails to compile on musl since the
> pt_regs type (used by .regs) is in an incomplete type which has to be
> completed by inclusion of the asm/ptrace.h Kernel header. Contrary to
> glibc, this header is not indirectly included by musl through other
> header files.
> 
> This patch fixes compilation of this code with musl libc by accessing
> the register values via .gp_regs/.gregs (depending on 32-bit or 64-bit
> PowerPC) instead of using .regs. For more details, see
> https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591261.html
> 
> For the offsets in gp_regs refer to the Kernel asm/ptrace.h header.
> 
> This patch has been tested on Alpine Linux ppc64le (uses musl libc).
> 
> Signed-off-by: Sören Tempel <soeren@soeren-tempel.net>
> 
> ChangeLog:
> 
> 	* libgo/runtime/go-signal.c (defined): Use .gp_regs/.gregs
> 	  to access ppc64/ppc32 registers.
> 	(dumpregs): Ditto.
> ---
> Changes since v1: Use .gp_regs/.gregs instead of .regs based on
> feedback by Rich Felker, thereby avoiding the need to include
> asm/ptrace.h for struct pt_regs.
> 
>  libgo/runtime/go-signal.c | 25 +++++++++++++++++--------
>  1 file changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
> index d30d1603adc..647ad606019 100644
> --- a/libgo/runtime/go-signal.c
> +++ b/libgo/runtime/go-signal.c
> @@ -224,7 +224,11 @@ getSiginfo(siginfo_t *info, void *context __attribute__((unused)))
>  #elif defined(__alpha__) && defined(__linux__)
>  	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc;
>  #elif defined(__PPC__) && defined(__linux__)
> -	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.regs->nip;
> +#ifdef __PPC64__
> +	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gp_regs[32];
> +#else
> +	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[32];
> +#endif
>  #elif defined(__PPC__) && defined(_AIX)
>  	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.jmp_context.iar;
>  #elif defined(__aarch64__) && defined(__linux__)
> @@ -338,16 +342,21 @@ dumpregs(siginfo_t *info __attribute__((unused)), void *context __attribute__((u
>  #elif defined(__PPC__) && defined(__LITTLE_ENDIAN__) && defined(__linux__)
>  	  {
>  		mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
> +#ifdef __PPC64__
> +		greg_t *gp = &m->gp_regs;
> +#else
> +		greg_t *gp = &m->gregs;
> +#endif

Have you tried compiling this? It looks like it's a constraint
violation because gregset_t has array type and & will produce a
pointer to the array type rather than a pointer to the first element.
You should drop the & to get the pointer to the first element.

Rich
  

Patch

diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index d30d1603adc..647ad606019 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -224,7 +224,11 @@  getSiginfo(siginfo_t *info, void *context __attribute__((unused)))
 #elif defined(__alpha__) && defined(__linux__)
 	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc;
 #elif defined(__PPC__) && defined(__linux__)
-	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.regs->nip;
+#ifdef __PPC64__
+	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gp_regs[32];
+#else
+	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[32];
+#endif
 #elif defined(__PPC__) && defined(_AIX)
 	ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.jmp_context.iar;
 #elif defined(__aarch64__) && defined(__linux__)
@@ -338,16 +342,21 @@  dumpregs(siginfo_t *info __attribute__((unused)), void *context __attribute__((u
 #elif defined(__PPC__) && defined(__LITTLE_ENDIAN__) && defined(__linux__)
 	  {
 		mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
+#ifdef __PPC64__
+		greg_t *gp = &m->gp_regs;
+#else
+		greg_t *gp = &m->gregs;
+#endif
 		int i;
 
 		for (i = 0; i < 32; i++)
-			runtime_printf("r%d %X\n", i, m->regs->gpr[i]);
-		runtime_printf("pc  %X\n", m->regs->nip);
-		runtime_printf("msr %X\n", m->regs->msr);
-		runtime_printf("cr  %X\n", m->regs->ccr);
-		runtime_printf("lr  %X\n", m->regs->link);
-		runtime_printf("ctr %X\n", m->regs->ctr);
-		runtime_printf("xer %X\n", m->regs->xer);
+			runtime_printf("r%d %X\n", i, gp[i]);
+		runtime_printf("pc  %X\n", gp[32]);
+		runtime_printf("msr %X\n", gp[33]);
+		runtime_printf("cr  %X\n", gp[38]);
+		runtime_printf("lr  %X\n", gp[36]);
+		runtime_printf("ctr %X\n", gp[35]);
+		runtime_printf("xer %X\n", gp[37]);
 	  }
 #elif defined(__PPC__) && defined(_AIX)
 	  {