I accidentally wandered into sparc arch and noticed this:
int
__libc_sigaction (int sig, __const struct sigaction *act, struct sigaction
*oact)
{
int ret;
struct old_kernel_sigaction kact, koact;
unsigned long stub = 0;
int saved_errno = errno;
if (act)
{
kact.k_sa_handler = act->sa_handler;
memcpy (&kact.sa_mask, &act->sa_mask, sizeof(sigset_t));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
HERE
if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO)!= 0)
stub = (unsigned long) &__rt_sigreturn_stub;
else
stub = (unsigned long) &__sigreturn_stub;
stub -= 8;
kact.sa_restorer = NULL;
}
IIUC struct old_kernel_sigaction is defined in
libc/sysdeps/linux/common/bits/kernel_sigaction.h
(sparc does not have special one, unlike some arches),
and sa_mask is a long:
struct old_kernel_sigaction {
__sighandler_t k_sa_handler;
unsigned long sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
IIUC long is 32-bit on 32-bit sparc.
But userspace sigset_t is a 64-bit thing.
The memcpy above seems to be wrong.
Doing
kact.sa_mask = act->sa_mask.__val[0];
is probably right - sigset_t is always a vector of longs.
Back-conversion seems to be similarly wrong.
Grepping for "old_kernel_sigaction", I see that closest
analog of sparc's sigaction() is in arm
(sysdeps/linux/arm/sigaction.c).
I am a bit surprised sparc does not use __syscall_rt_sigaction.
Every other arch either uses __syscall_rt_sigaction exclusively,
avoiding struct old_kernel_sigaction conversion,
or has an #ifdef to use __syscall_rt_sigaction if it is present,
which I presume is always true for many years.
(to be precise, only these arches mention old_kernel_sigaction:
./sysdeps/linux/arm/sigaction.c
./sysdeps/linux/i386/sigaction.c
./sysdeps/linux/mips/sigaction.c
./sysdeps/linux/x86_64/sigaction.c
)
Is sparc special in this regard?
--
vda
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc