Re: [PATCH] libgo: include asm/ptrace.h for pt_regs definition on PowerPC

1 view
Skip to first unread message

Sören Tempel

unread,
Feb 21, 2022, 11:47:26 AM2/21/22
to gcc-p...@gcc.gnu.org, gofront...@googlegroups.com
Ping.

Summary: Fix build of libgo on PPC with musl libc and libucontext by
explicitly including the Linux header defining `struct pt_regs` instead of
relying on other libc headers to include it implicitly.

See: https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587520.html

If the patch needs to be revised further please let me know. This patch has
been applied at Alpine Linux downstream (which uses musl libc) for a while, I
have not tested it on other systems.

Greetings,
Sören

Sören Tempel <soe...@soeren-tempel.net> wrote:
> Both glibc and musl libc declare pt_regs as an incomplete type. This
> type has to be completed by inclusion of another header. On Linux, the
> asm/ptrace.h header file provides this type definition. Without
> including this header file, it is not possible to access the regs member
> of the mcontext_t struct as done in libgo/runtime/go-signal.c. On glibc,
> other headers (e.g. sys/user.h) include asm/ptrace.h but on musl
> asm/ptrace.h is not included by other headers and thus the
> aforementioned files do not compile without an explicit include of
> asm/ptrace.h:
>
> libgo/runtime/go-signal.c: In function 'getSiginfo':
> libgo/runtime/go-signal.c:227:63: error: invalid use of undefined type 'struct pt_regs'
> 227 | ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.regs->nip;
> |
>
> See also:
>
> * https://git.musl-libc.org/cgit/musl/commit/?id=c2518a8efb6507f1b41c3b12e03b06f8f2317a1f
> * https://github.com/kaniini/libucontext/issues/36
>
> Signed-off-by: Sören Tempel <soe...@soeren-tempel.net>
>
> ChangeLog:
>
> * libgo/runtime/go-signal.c: Include asm/ptrace.h for the
> definition of pt_regs (used by mcontext_t) on PowerPC.
> ---
> libgo/runtime/go-signal.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
> index d30d1603adc..fc01e04e4a1 100644
> --- a/libgo/runtime/go-signal.c
> +++ b/libgo/runtime/go-signal.c
> @@ -10,6 +10,12 @@
> #include <sys/time.h>
> #include <ucontext.h>
>
> +// On PowerPC, ucontext.h uses a pt_regs struct as an incomplete
> +// type. This type must be completed by including asm/ptrace.h.
> +#ifdef __PPC__
> +#include <asm/ptrace.h>
> +#endif
> +
> #include "runtime.h"
>
> #ifndef SA_RESTART

Ian Lance Taylor

unread,
Feb 21, 2022, 12:25:55 PM2/21/22
to Sören Tempel, gcc-p...@gcc.gnu.org, gofront...@googlegroups.com
Note for gofrontend-dev: on gcc-patches only Andreas Schwab suggested
using uc_regs instead of regs, which does look correct to me.

Ian
> --
> You received this message because you are subscribed to the Google Groups "gofrontend-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to gofrontend-de...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/gofrontend-dev/2FICMX0ORZ6O1.3DYXRTDHNGXCN%408pit.net.

Sören Tempel

unread,
Mar 6, 2022, 7:49:07 AM3/6/22
to Ian Lance Taylor, sch...@linux-m68k.org, gcc-p...@gcc.gnu.org, gofront...@googlegroups.com
What would be the benefit of using .uc_regs instead of .regs? The
current code works entirely fine as it, it just needs an include of the
Linux Kernel header defining the pt_regs type (which my proposed patch
adds).

Furthermore, it seems to me that .uc_regs is only available on powerpc
but not on power64 [1]? musl libc also only defines the .uc_regs member
for powerpc [2] and not for powerpc64 [3] on ucontext_t.

Is there any documentation for .uc_regs on PowerPC?

Sincerely,
Sören

[1]: https://github.com/torvalds/linux/blob/c3617f72036c909e1f6086b5b9e364e0ef90a6da/arch/powerpc/include/uapi/asm/ucontext.h#L24-L27
[2]: https://git.musl-libc.org/cgit/musl/tree/arch/powerpc/bits/signal.h?id=f8bdc3048216f41eaaf655524fa286cfb1184a70#n67
[3]: https://git.musl-libc.org/cgit/musl/tree/arch/powerpc64/bits/signal.h?id=f8bdc3048216f41eaaf655524fa286cfb1184a70#n56

Rich Felker

unread,
Mar 7, 2022, 12:52:05 AM3/7/22
to Ian Lance Taylor, gofront...@googlegroups.com, gcc-p...@gcc.gnu.org, Sören Tempel
On Sun, Mar 06, 2022 at 10:22:56AM -0500, Rich Felker wrote:
> On Mon, Feb 21, 2022 at 09:25:43AM -0800, Ian Lance Taylor via Gcc-patches wrote:
> > Note for gofrontend-dev: on gcc-patches only Andreas Schwab suggested
> > using uc_regs instead of regs, which does look correct to me.
>
> Yes, this is absolutely the correct fix. Having pt_regs appear at all
> in code not using ptrace is a serious code smell.
>
> The root of this problem is twofold: (1) ancient Linux (2.0.x?) had a
> bad definition of powerpc32 ucontext_t that lacked any mcontext_t,
> instead having a regs member pointing to the storage for the register
> state (as pt_regs). This was ostensibly done for extensibility
> reasons, but was non-POSIX-conforming and broken, and was later fixed.
>
> And (2) glibc's definition of ucontext_t is also non-conforming,
> making the uc_mcontext member have type anon-union rather than type
> mcontext_t.
>
> musl does not follow this but puts the uc_mcontext member in the place
> later kernel ABI assigned to it after the kernel mistake was fixed.
>
> Ideally you would access uc_mcontext.gregs[32] (32==NIP) and be done
> with it, but this won't work on glibc because of (2). However musl
> also supports the old uc_regs pointer (it's in the reserved namespace
> anyway so not a conformance error), making it so uc_regs->gregs[32]
> works on either.

I mistakenly thought this was ppc32 because I wasn't remembering that
a lesser mess was still present on ppc64. The above applies to ppc32.
On ppc64 it would be uc_mcontext.gp_regs[32].

I'm not sure if the code is intended to also work on ppc32, but even
if that's not supported now, when fixing this it should probably
condition the use of gregs/gp_regs name on __WORDSIZE or whatever so
that, if anyone ever does try to add ppc32 support, they don't get
bogged down in this again and get it wrong again...

Rich

Rich Felker

unread,
Mar 7, 2022, 12:52:05 AM3/7/22
to Ian Lance Taylor, Sören Tempel, gcc-p...@gcc.gnu.org, gofront...@googlegroups.com
On Mon, Feb 21, 2022 at 09:25:43AM -0800, Ian Lance Taylor via Gcc-patches wrote:
> Note for gofrontend-dev: on gcc-patches only Andreas Schwab suggested
> using uc_regs instead of regs, which does look correct to me.

Yes, this is absolutely the correct fix. Having pt_regs appear at all
in code not using ptrace is a serious code smell.

The root of this problem is twofold: (1) ancient Linux (2.0.x?) had a
bad definition of powerpc32 ucontext_t that lacked any mcontext_t,
instead having a regs member pointing to the storage for the register
state (as pt_regs). This was ostensibly done for extensibility
reasons, but was non-POSIX-conforming and broken, and was later fixed.

And (2) glibc's definition of ucontext_t is also non-conforming,
making the uc_mcontext member have type anon-union rather than type
mcontext_t.

musl does not follow this but puts the uc_mcontext member in the place
later kernel ABI assigned to it after the kernel mistake was fixed.

Ideally you would access uc_mcontext.gregs[32] (32==NIP) and be done
with it, but this won't work on glibc because of (2). However musl
also supports the old uc_regs pointer (it's in the reserved namespace
anyway so not a conformance error), making it so uc_regs->gregs[32]
works on either.

Rich
Reply all
Reply to author
Forward
0 new messages