From 09753fb104540acfd48f8c0bd79d1cd832ed4c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwenol=C3=A9=20Beauchesne?= Date: Sun, 10 Nov 2002 11:59:43 +0000 Subject: Fix implementation of signal() for x86-64, adjust for new kernel-headers --- mdk-stage1/minilibc.c | 66 ++++++++++++++++----------------------------------- 1 file changed, 21 insertions(+), 45 deletions(-) diff --git a/mdk-stage1/minilibc.c b/mdk-stage1/minilibc.c index 0a9bc9156..7a7e6c561 100644 --- a/mdk-stage1/minilibc.c +++ b/mdk-stage1/minilibc.c @@ -61,60 +61,37 @@ void _fini (int __status __attribute__ ((unused))) } #ifdef __x86_64__ +/* x86-64 implementation of signal() derived from glibc sources */ -#define _NSIG 64 -#define _NSIG_BPW 64 -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - -typedef struct { - unsigned long sig[_NSIG_WORDS]; -} libc_sigset_t; - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, void*, void*); - } _u; - unsigned long sa_flags; - void (*sa_restorer)(void); - libc_sigset_t sa_mask; -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -static inline int sigemptyset(libc_sigset_t *set) { - set->sig[0]=0; - if (_NSIG_WORDS>1) set->sig[1]=0; - if (_NSIG_WORDS>2) { - set->sig[2]=0; - set->sig[3]=0; - } +static inline int sigemptyset(sigset_t *set) { + *set = 0; return 0; } -#define __sigmask(sig) ( ((unsigned long)1) << (((sig)-1) % (8*sizeof(unsigned long))) ) -#define __sigword(sig) ( ((sig)-1) / (8*sizeof(unsigned long)) ) - -#define EINVAL 22 - -int sigaddset(libc_sigset_t *set, int signo) { - if ((signo<1)||(signo>SIGRTMAX)) { - errno = EINVAL; - return -1; - } else { - unsigned long __mask = __sigmask (signo); - unsigned long __word = __sigword (signo); - set->sig[__word]|=__mask; - return 0; - } +static inline int sigaddset(sigset_t *set, int sig) { + __asm__("btsq %1,%0" : "=m" (*set) : "Ir" (sig - 1L) : "cc"); + return 0; } #define __NR___rt_sigaction __NR_rt_sigaction static inline _syscall3(int,__rt_sigaction,int,signum,const void *,act,void *,oldact) +#define __NR___rt_sigreturn __NR_rt_sigreturn +static _syscall1(int,__rt_sigreturn,unsigned long,unused) + +static void restore_rt(void) { + __rt_sigreturn(0); +} int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) { - return __rt_sigaction(signum, act, oldact); + struct sigaction *newact = (struct sigaction *)act; + if (act) { + newact = __builtin_alloca(sizeof(*newact)); + newact->sa_handler = act->sa_handler; + newact->sa_flags = act->sa_flags | SA_RESTORER; + newact->sa_restorer = &restore_rt; + newact->sa_mask = act->sa_mask; + } + return __rt_sigaction(signum, newact, oldact); } __sighandler_t signal(int signum, __sighandler_t action) { @@ -329,4 +306,3 @@ void printf(char * fmt, ...) } } } - -- cgit v1.2.1