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 uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc