From: Sören Tempel <soeren+...@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 <soe...@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
                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)
          {

Reply via email to