[RFC 1/2] tools/nolibc: add sigaction()
Berg, Benjamin
benjamin.berg at intel.com
Thu Jun 26 23:46:56 PDT 2025
On Fri, 2025-06-27 at 06:48 +0200, Thomas Weißschuh wrote:
> On Thu, Jun 26, 2025 at 09:57:13PM +0200, Benjamin Berg wrote:
> > From: Benjamin Berg <benjamin.berg at intel.com>
> >
> > In preparation to add tests that use it.
>
> I tried to implement signal support in nolibc before but ran into some issues.
> Unfortunately I don't remember the details.
> But I guess you know more about signals than me, so let's try it again.
> In any case this should add some tests to
> tools/testing/selftests/nolibc/nolibc-test.c.
>
> If you test it with qemu-user please be aware that there were issues around
> SA_RESTORER up until recently [0] [1].
Oh, is there a convenient way to cross-compile for various
architectures and run them using qemu?
So far I only tried x86/x86_64.
>
> [1] https://lore.kernel.org/qemu-devel/20250202-riscv-sa-restorer-v1-1-6f4bf814a1dd@t-8ch.de/
> [0] https://lore.kernel.org/qemu-devel/mvmed060xc9.fsf@suse.de/
>
> >
> > Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
> > ---
> > tools/include/nolibc/nolibc.h | 3 +++
> > tools/include/nolibc/signal.h | 34 ++++++++++++++++++++++++++++++++++
> > 2 files changed, 37 insertions(+)
> >
> > diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h
> > index c199ade200c2..29e37a755aba 100644
> > --- a/tools/include/nolibc/nolibc.h
> > +++ b/tools/include/nolibc/nolibc.h
> > @@ -92,6 +92,9 @@
> > #ifndef _NOLIBC_H
> > #define _NOLIBC_H
> >
> > +/* So that we do not get compatibility types/defines */
> > +#define __KERNEL__
>
> Could you explain this more?
>
> The user may have included kernel UAPI headers already before including nolibc,
> so it doesn't really work.
Maybe we should just set it in the CFLAGS directly then?
Honestly, I am not entirely sure how you are supposed to do it
correctly. The thing is, if I do not set __KERNEL__, then I get the old
compatibility defines and types from asm/signal.h.
And, I do not see an alternative way. It would not be safe to avoid the
include entirely and if you try that you are also missing the
SA_RESTORER define for the proper "struct sigaction" definition to be
correct.
The best alternative I see would be copying the proper definitions into
the architecture specific header. That would also be ugly, as one would
need to do a "struct sigaction" -> "struct nolibc_rt_sigaction"
conversion internally. But, that would have the advantage that nolibc
works outside of the kernel tree.
Even if all this is ugly, I would prefer that over using the
compatibility sigaction syscall instead of rt_sigaction.
> > +
> > #include "std.h"
> > #include "arch.h"
> > #include "types.h"
> > diff --git a/tools/include/nolibc/signal.h b/tools/include/nolibc/signal.h
> > index ac13e53ac31d..fa52119e577f 100644
> > --- a/tools/include/nolibc/signal.h
> > +++ b/tools/include/nolibc/signal.h
> > @@ -14,6 +14,7 @@
> > #include "arch.h"
> > #include "types.h"
> > #include "sys.h"
> > +#include <linux/signal.h>
> >
> > /* This one is not marked static as it's needed by libgcc for divide by zero */
> > int raise(int signal);
> > @@ -23,4 +24,37 @@ int raise(int signal)
> > return sys_kill(sys_getpid(), signal);
> > }
> >
> > +/*
> > + * sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
> > + */
> > +
> > +#ifdef SA_RESTORER
> > +__attribute__((naked))
>
> __attribute__((naked)) is not supported everywhere.
One can just drop it. It just felt it was cleaner as we really just
want to set the register and do the syscall without modifying the
stack.
> > +static void my_sa_restorer(void)
>
> This should use a name with less potential to conflict with user code.
> Like __nolibc_sa_restorer().
Sure!
Benjamin
>
> > +{
> > + my_syscall0(__NR_rt_sigreturn);
> > +}
> > +#endif
> > +
> > +static __attribute__((unused))
> > +int sys_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
> > +{
> > + struct sigaction real_act = *act;
> > +#ifdef SA_RESTORER
> > + if (!(real_act.sa_flags & SA_RESTORER)) {
> > + real_act.sa_flags |= SA_RESTORER;
> > + real_act.sa_restorer = my_sa_restorer;
> > + }
> > +#endif
> > +
> > + return my_syscall4(__NR_rt_sigaction, signum, &real_act, oldact,
> > + sizeof(act->sa_mask));
>
> No need for the linebreak.
>
> > +}
> > +
> > +static __attribute__((unused))
> > +int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
> > +{
> > + return __sysret(sys_sigaction(signum, act, oldact));
> > +}
> > +
> > #endif /* _NOLIBC_SIGNAL_H */
> > --
> > 2.50.0
> >
Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928
More information about the linux-um
mailing list