diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/sparc')
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/Dist | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/Makefile | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S | 142 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/brk.c | 56 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/profil-counter.h | 35 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sigaction.c | 127 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/socket.S | 58 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/syscall.S | 30 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sysdep.h | 57 |
9 files changed, 510 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/sparc/Dist b/sysdeps/unix/sysv/linux/sparc/Dist new file mode 100644 index 0000000000..6134c6056d --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/Dist @@ -0,0 +1,2 @@ +__sigtrampoline.S +clone.S diff --git a/sysdeps/unix/sysv/linux/sparc/Makefile b/sysdeps/unix/sysv/linux/sparc/Makefile new file mode 100644 index 0000000000..629e6b37df --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),signal) +sysdep_routines += __sigtrampoline +endif diff --git a/sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S b/sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S new file mode 100644 index 0000000000..d0fe760270 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/__sigtrampoline.S @@ -0,0 +1,142 @@ +/* Userland trampoline code for sigaction on Linux/SPARC */ +/* (C) 1996, 1997 Free Software Foundation, Inc. */ +/* This file is part of the GNU C Library. */ +/* Contributed by Miguel de Icaza (miguel@gnu.ai.mit.edu) */ +/* Many thanks go to David Miller for explaining all this to me */ +/* miguel@nuclecu.unam.mx */ +/* Sources: David Miller, 4.4BSD/SPARC code */ + +#include <sysdep.h> + +/* For REGWIN_SZ */ +#include <asm/ptrace.h> +#include <asm/psr.h> + +/* The C compiler frame size */ +#define CCFSZ 96 + + .text + +ENTRY(____sparc_signal_trampoline) + .global SYMBOL_NAME(____sig_table) + + /* Make room for 32 %f registers + %fsr + * this is 132 bytes + alignement = 136 + * 96 is the C frame size + */ + save %sp,-136-CCFSZ,%sp + + /* save regular registers */ + mov %g2,%l2 + mov %g3,%l3 + mov %g4,%l4 + mov %g5,%l5 + mov %g6,%l6 + mov %g7,%l7 + + /* save fpu registers */ + ld [%fp+64+16+20],%l0 /* load the psr from sigcontext */ + sethi %hi(PSR_EF),%l1 + andcc %l0,%l1,%l0 /* is floating point enabled? */ + be 1f + rd %y,%l1 /* save y anyways */ + + /* save fpu registers */ + st %fsr, [%sp + CCFSZ + 0] + std %f0, [%sp + CCFSZ + 8] + std %f2, [%sp + CCFSZ + 16] + std %f4, [%sp + CCFSZ + 24] + std %f6, [%sp + CCFSZ + 32] + std %f8, [%sp + CCFSZ + 40] + std %f10, [%sp + CCFSZ + 48] + std %f12, [%sp + CCFSZ + 56] + std %f14, [%sp + CCFSZ + 64] + std %f16, [%sp + CCFSZ + 72] + std %f18, [%sp + CCFSZ + 80] + std %f20, [%sp + CCFSZ + 88] + std %f22, [%sp + CCFSZ + 96] + std %f24, [%sp + CCFSZ + 104] + std %f26, [%sp + CCFSZ + 112] + std %f28, [%sp + CCFSZ + 120] + std %f30, [%sp + CCFSZ + 128] + +1: + /* Load signal number */ + ld [%fp + REGWIN_SZ],%o0 + mov %fp,%o1 + mov 0xfea,%o2 + + /* Sanity check */ + cmp %o0,33 + bl 1f + or %g0,%g0,%g1 /*Call sys_setup */ + t 0x10 +1: +#ifdef __PIC__ + /* Save return address */ + mov %o7,%o4 +___sxx: + call ___syy + nop +___syy: + sethi %hi(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5 + or %o5,%lo(_GLOBAL_OFFSET_TABLE_-(___sxx-.)),%o5 + add %o7,%o5,%o5 + /* restore return address */ + mov %o4,%o7 + mov %o5,%o4 + /* o4 has the GOT pointer */ +#endif + sethi %hi(SYMBOL_NAME(____sig_table)),%o5 + or %o5,%lo(SYMBOL_NAME(____sig_table)),%o5 +#ifdef __PIC__ + add %o5,%o4,%o4 + ld [%o4],%o5 +#endif + sll %o0,2,%o4 + add %o5,%o4,%o4 + ld [%o4],%o4 + ld [%fp + REGWIN_SZ + 4],%o1 /* Load subcode */ + ld [%fp + REGWIN_SZ + 8],%o2 /* pointer to sigcontext */ + call %o4 + ld [%fp + REGWIN_SZ + 12],%o3 /* Address where signal ocurred */ + + /* handler returned, restore state */ + tst %l0 + be 1f + wr %l1,%g0,%y + + /* fpu restoration */ + ld [%sp + CCFSZ + 0], %fsr + ldd [%sp + CCFSZ + 8], %f0 + ldd [%sp + CCFSZ + 16], %f2 + ldd [%sp + CCFSZ + 24], %f4 + ldd [%sp + CCFSZ + 32], %f6 + ldd [%sp + CCFSZ + 40], %f8 + ldd [%sp + CCFSZ + 48], %f10 + ldd [%sp + CCFSZ + 56], %f12 + ldd [%sp + CCFSZ + 64], %f14 + ldd [%sp + CCFSZ + 72], %f16 + ldd [%sp + CCFSZ + 80], %f18 + ldd [%sp + CCFSZ + 88], %f20 + ldd [%sp + CCFSZ + 96], %f22 + ldd [%sp + CCFSZ + 104], %f24 + ldd [%sp + CCFSZ + 112], %f26 + ldd [%sp + CCFSZ + 120], %f28 + ldd [%sp + CCFSZ + 128], %f30 + +1: + mov %l2,%g2 + mov %l3,%g3 + mov %l4,%g4 + mov %l5,%g5 + mov %l6,%g6 + mov %l7,%g7 + + /* call sigreturn */ + restore %g0,SYS_sigreturn,%g1 /* register back and set syscall */ + add %sp,64+16,%o0 + t 0x10 + /* if we return, sysreturn failed */ + mov SYS_exit,%g1 + t 0x10 diff --git a/sysdeps/unix/sysv/linux/sparc/brk.c b/sysdeps/unix/sysv/linux/sparc/brk.c new file mode 100644 index 0000000000..13bcb0459b --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/brk.c @@ -0,0 +1,56 @@ +/* brk system call for Linux/SPARC. + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx) + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <unistd.h> +#include <sysdep.h> + +/* This must be initialized data because commons can't have aliases. */ +void *__curbrk = 0; + +/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt + to work around different old braindamage in the old Linux ELF dynamic + linker. */ +weak_alias (__curbrk, ___brk_addr) + +int +__brk (void *addr) +{ + void *newbrk, *scratch; + + asm ("mov %1, %%g1\n\t" + "mov %2, %%o0\n\t" + "t 0x10\n\t" + "mov %%o0, %0\n\t" + : "=r" (newbrk) + : "0" (SYS_brk), "r" (addr) + : "g1", "o0"); + + __curbrk = newbrk; + + if (newbrk < addr) + { + __set_errno (ENOMEM); + return -1; + } + + return 0; +} +weak_alias (__brk, brk) diff --git a/sysdeps/unix/sysv/linux/sparc/profil-counter.h b/sysdeps/unix/sysv/linux/sparc/profil-counter.h new file mode 100644 index 0000000000..1998c34ed5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/profil-counter.h @@ -0,0 +1,35 @@ +/* Low-level statistical profiling support function. Linux/SPARC version. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sigcontext.h> + +void +profil_counter (int signo, __siginfo_t si) +{ + extern int __sparc_old_signals; + + if (__sparc_old_signals) + { + struct sigcontext_struct *s = (void *) &si; + + profil_count ((void *) s->sigc_pc); + } + else + profil_count ((void *) si.si_regs.pc); +} diff --git a/sysdeps/unix/sysv/linux/sparc/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sigaction.c new file mode 100644 index 0000000000..e7bda77de2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sigaction.c @@ -0,0 +1,127 @@ +/* POSIX.1 sigaction call for Linux/SPARC. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx), 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <syscall.h> +#include <sys/signal.h> +#include <errno.h> + +/* 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); +long ____sig_table [NSIG]; + +int +__trampoline_sigaction (int sig, struct sigaction *new, struct sigaction *old) +{ + int ret; + int need_to_hide_trick = 0; + __sighandler_t old_sh; + + if (new) + { + 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; + } + } + __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" (SYS_sigaction), "1" (sig), "2" (new), "3" (old) + : "g1", "o0", "o1", "o2"); + + if (ret >= 0) + { + if (old && old->sa_handler == ____sparc_signal_trampoline) + { + if (need_to_hide_trick) + old->sa_handler = old_sh; + else + old->sa_handler = ____sig_table[sig]; + } + if (need_to_hide_trick) + new->sa_handler = ____sig_table[sig]; + return 0; + } + __set_errno (-ret); + return -1; +} + +int +__new_sigaction (int sig, 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" (SYS_sigaction), "1" (sig), "2" (new), "3" (old) + : "g1", "o0", "o1", "o2"); + if (ret >= 0) + return 0; + __set_errno (-ret); + return -1; +} + +int +__sigaction (int sig, struct sigaction *new, struct sigaction *old) +{ + static (*sigact_routine) (int, 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); +} +weak_alias (__sigaction, sigaction); diff --git a/sysdeps/unix/sysv/linux/sparc/socket.S b/sysdeps/unix/sysv/linux/sparc/socket.S new file mode 100644 index 0000000000..f8075201db --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/socket.S @@ -0,0 +1,58 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <sysdep.h> +#include <sys/socketcall.h> + +#define P(a, b) P2(a, b) +#define P2(a, b) a##b + + .text +/* The socket-oriented system calls are handled unusally in Linux. + They are all gated through the single `socketcall' system call number. + `socketcall' takes two arguments: the first is the subcode, specifying + which socket function is being called; and the second is a pointer to + the arguments to the specific function. + + The .S files for the other calls just #define socket and #include this. */ + +.globl P(__,socket) +ENTRY (P(__,socket)) + mov SYS_ify(socketcall), %g1 /* System call number */ + + /* Use ## so `socket' is a separate token that might be #define'd. */ + mov P(SOCKOP_,socket), %o0 /* Subcode is first arg to syscall. */ + mov %i0,%o1 /* args pointer is second arg to syscall */ + + t 0x10 + bcc,a 1 + nop + save %sp,96,%sp + call __errno_location + nop + st %i0,[%o0] + restore + retl + mov -1,%o0 +1: + ret + +PSEUDO_END (P(__,socket)) + +weak_alias (P(__,socket), socket) diff --git a/sysdeps/unix/sysv/linux/sparc/syscall.S b/sysdeps/unix/sysv/linux/sparc/syscall.S new file mode 100644 index 0000000000..4166e4231b --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/syscall.S @@ -0,0 +1,30 @@ +/* Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#define DONT_LOAD_G1 +#include <sysdep.h> +ENTRY (__libc_syscall) + or %o0,%g0,%g1 + or %o1,%g0,%o0 + or %o2,%g0,%o1 + or %o3,%g0,%o2 + or %o4,%g0,%o3 + or %o5,%g0,%o4 +PSEUDO_NOENT(__libc_syscall, syscall, 5) + ret +SYSCALL__POST(syscall,5) diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sysdep.h new file mode 100644 index 0000000000..0251a1f014 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sysdep.h @@ -0,0 +1,57 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Miguel de Icaza <miguel@gnu.ai.mit.edu>, January 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _LINUX_SPARC_SYSDEP_H +#define _LINUX_SPARC_SYSDEP_H 1 + +#include <sysdeps/unix/sparc/sysdep.h> + +#undef SYS_ify +#define SYS_ify(syscall_name) __NR_##syscall_name + +#ifdef ASSEMBLER + +#ifdef DONT_LOAD_G1 +# define LOADSYSCALL(x) +#else +# define LOADSYSCALL(x) mov SYS_##n, %g1 +#endif + +/* Linux/SPARC uses a different trap number and uses __errno_location always */ +#undef PSEUDO + +#define PSEUDO(name, syscall_name, args) \ + .text; \ + ENTRY(name); \ + LOADSYSCALL(syscall_name); \ + ta 0x10; \ + bcc,a 1f; \ + nop; \ + save %sp,96,%sp; \ + call __errno_location; \ + nop; \ + st %i0,[%o0]; \ + restore; \ + retl; \ + mov -1,%o0; \ +1: + +#endif /* ASSEMBLER */ + +#endif /* linux/sparc/sysdep.h */ |