diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc32/clone.S | 43 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c | 131 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc32/socket.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc64/clone.S | 13 |
4 files changed, 69 insertions, 120 deletions
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S index 64735e9dbc..e053569650 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/clone.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. Contributed by Richard Henderson (rth@tamu.edu). The GNU C Library is free software; you can redistribute it and/or @@ -26,21 +26,18 @@ .text .align 4 - .globl __libc_clone - .type __libc_clone,@function - .weak clone - __clone = __libc_clone - clone = __libc_clone + .globl __clone + .type __clone,@function -__libc_clone: +__clone: save %sp,-96,%sp /* sanity check arguments */ tst %i0 - be __clone_syscall_error - tst %i1 - be __clone_syscall_error - nop + be .Lerror + tst %i1 + be .Lerror + nop /* Do the system call */ mov %i1,%o1 @@ -48,23 +45,31 @@ __libc_clone: set __NR_clone,%g1 ta 0x10 bcs __clone_syscall_error - tst %o1 + tst %o1 bne __thread_start - nop + nop mov %o0,%i0 ret - restore + restore -__clone_syscall_error: +.Lerror: call __errno_location - set EINVAL,%i0 + set EINVAL,%i0 st %i0,[%o0] mov -1,%i0 ret - restore + restore + + .size __clone, .-__clone + + .type __thread_start,@function __thread_start: call %i0 - mov %i3,%o0 + mov %i3,%o0 call _exit,0 - nop + nop + + .size __thread_start, .-__thread_start + +weak_alias(__clone, clone) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c index 0fab662064..b9c20ddcd0 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c @@ -21,120 +21,65 @@ #include <syscall.h> #include <sys/signal.h> #include <errno.h> +#include <kernel_sigaction.h> /* The variable is shared between all wrappers around signal handling functions which have RT equivalents. */ int __libc_missing_rt_sigs; -/* Commented out while I figure out what the fuck goes on */ -long ____sig_table [NSIG]; -#if 0 - -/* The kernel will deliver signals in the old way if the signal - number is a positive number. The kernel will deliver a signal - with the new stack layout if the signal number is a negative number. - - Our sigaction code takes care of selecting the type of kernel we are - using at runtime. */ - -extern void ____sparc_signal_trampoline (int); - int -__trampoline_sigaction (int sig, struct sigaction *new, struct sigaction *old) +__sigaction (int sig, __const struct sigaction *act, struct sigaction *oact) { int ret; - int need_to_hide_trick = 0; - __sighandler_t old_sh; + struct kernel_sigaction k_sigact, k_osigact; - if (new) + /* Magic to tell the kernel we are using "new-style" signals, in that + the signal table is not kept in userspace. Not the same as the + really-new-style rt signals. */ + sig = -sig; + + if (act) { - if (new->sa_handler != SIG_DFL && new->sa_handler != SIG_IGN) - { - old_sh = ____sig_table[sig]; - ____sig_table[sig] = (long int) new->sa_handler; - new->sa_handler = ____sparc_signal_trampoline; - need_to_hide_trick = 1; - } + k_sigact.sa_handler = act->sa_handler; + k_sigact.sa_mask = act->sa_mask.__val[0]; + k_sigact.sa_flags = act->sa_flags; } - __asm__("or %%g0,%0,%%g1\n\t" - "or %%g0,%1,%%o0\n\t" - "or %%g0,%2,%%o1\n\t" - "or %%g0,%3,%%o2\n\t" - "t 0x10\n\t" - "bcc 1f\n\t" - "or %%o0, %%g0, %0\n\t" - "sub %%g0, %%o0, %0\n\t" - "1:" - : "=r" (ret), "=r" ((long int) sig), "=r" ((long int) new), - "=r" ((long int) old) - : "0" (__NR_sigaction), "1" (sig), "2" (new), "3" (old) - : "g1", "o0", "o1", "o2"); + + { + register int r_syscallnr __asm__("%g1") = __NR_sigaction; + register int r_sig __asm__("%o0") = sig; + register struct kernel_sigaction *r_act __asm__("%o1"); + register struct kernel_sigaction *r_oact __asm__("%o2"); + + r_act = act ? &k_sigact : NULL; + r_oact = oact ? &k_osigact : NULL; + + __asm__ __volatile__("t 0x10\n\t" + "bcc 1f\n\t" + " nop\n\t" + " sub %%g0,%%o0,%%o0\n" + "1:" + : "=r"(r_sig) + : "r"(r_syscallnr), "r"(r_act), "r"(r_oact), + "0"(r_sig)); + + ret = r_sig; + } if (ret >= 0) { - if (old && old->sa_handler == ____sparc_signal_trampoline) + if (oact) { - if (need_to_hide_trick) - old->sa_handler = old_sh; - else - old->sa_handler = ____sig_table[sig]; + oact->sa_handler = k_osigact.sa_handler; + oact->sa_mask.__val[0] = k_osigact.sa_mask; + oact->sa_flags = k_osigact.sa_flags; + oact->sa_restorer = NULL; } - if (need_to_hide_trick) - new->sa_handler = ____sig_table[sig]; return 0; } - __set_errno (-ret); - return -1; -} -#else -# define __new_sigaction __sigaction -#endif -int -__new_sigaction (int sig, __const struct sigaction *new, struct sigaction *old) -{ - int ret; - - sig = -sig; - - __asm__("or %%g0,%0,%%g1\n\t" - "or %%g0,%1,%%o0\n\t" - "or %%g0,%2,%%o1\n\t" - "or %%g0,%3,%%o2\n\t" - "t 0x10\n\t" - "bcc 1f\n\t" - "or %%o0, %%g0, %0\n\t" - "sub %%g0,%%o0,%0\n\t" - "1:" - : "=r" (ret), "=r" ((long int) sig), "=r" ((long int) new), - "=r" ((long int) old) - : "0" (__NR_sigaction), "1" (sig), "2" (new), "3" (old) - : "g1", "o0", "o1", "o2"); - if (ret >= 0) - return 0; __set_errno (-ret); return -1; } -#if 0 -int -__sigaction (int sig, __const struct sigaction *new, struct sigaction *old) -{ - static (*sigact_routine) (int, __const struct sigaction *, struct sigaction *); - int ret; - struct sigaction sa; - - if (sigact_routine) - return (*sigact_routine) (sig, new, old); - - ret = __new_sigaction (1, NULL, &sa); - if (ret == -1) - sigact_routine = __trampoline_sigaction; - else - sigact_routine = __new_sigaction; - - return __sigaction (sig, new, old); -} -#endif - weak_alias (__sigaction, sigaction); diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S index 8d6fd77c10..a6cb324363 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/socket.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997. diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S index a16f9b7c9b..6c619fcdc3 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/clone.S @@ -26,13 +26,10 @@ .text .align 4 - .globl __libc_clone - .type __libc_clone,@function - .weak clone - __clone = __libc_clone - clone = __libc_clone + .globl __clone + .type __clone,@function -__libc_clone: +__clone: save %sp,-160,%sp /* sanity check arguments */ @@ -77,7 +74,7 @@ __libc_clone: mov -1,%i0 ret restore - .size __libc_clone, .-__libc_clone + .size __clone, .-__clone .type __thread_start,@function __thread_start: @@ -88,3 +85,5 @@ __thread_start: call _exit,0 nop .size __thread_start, .-__thread_start + +weak_alias(__clone, clone) |