diff options
Diffstat (limited to 'sysdeps/mach')
-rw-r--r-- | sysdeps/mach/alpha/machine-lock.h | 80 | ||||
-rw-r--r-- | sysdeps/mach/alpha/machine-sp.h | 36 | ||||
-rw-r--r-- | sysdeps/mach/alpha/setfpucw.c | 69 | ||||
-rw-r--r-- | sysdeps/mach/alpha/syscall.S | 37 | ||||
-rw-r--r-- | sysdeps/mach/alpha/sysdep.h | 59 | ||||
-rw-r--r-- | sysdeps/mach/alpha/thread_state.h | 39 | ||||
-rw-r--r-- | sysdeps/mach/hurd/alpha/bits/sigcontext.h | 73 | ||||
-rw-r--r-- | sysdeps/mach/hurd/alpha/exc2signal.c | 75 | ||||
-rw-r--r-- | sysdeps/mach/hurd/alpha/init-first.c | 302 | ||||
-rw-r--r-- | sysdeps/mach/hurd/alpha/intr-msg.h | 100 | ||||
-rw-r--r-- | sysdeps/mach/hurd/alpha/longjmp-ts.c | 49 | ||||
-rw-r--r-- | sysdeps/mach/hurd/alpha/sigreturn.c | 211 | ||||
-rw-r--r-- | sysdeps/mach/hurd/alpha/static-start.S | 30 | ||||
-rw-r--r-- | sysdeps/mach/hurd/alpha/trampoline.c | 249 |
14 files changed, 0 insertions, 1409 deletions
diff --git a/sysdeps/mach/alpha/machine-lock.h b/sysdeps/mach/alpha/machine-lock.h deleted file mode 100644 index bd27d2a51f..0000000000 --- a/sysdeps/mach/alpha/machine-lock.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Machine-specific definition for spin locks. Alpha version. - Copyright (C) 1994, 1997, 2007 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _MACHINE_LOCK_H -#define _MACHINE_LOCK_H - -/* The type of a spin lock variable. */ - -typedef __volatile long int __spin_lock_t; - -/* Value to initialize `__spin_lock_t' variables to. */ - -#define __SPIN_LOCK_INITIALIZER 0L - - -#ifndef _EXTERN_INLINE -#define _EXTERN_INLINE __extern_inline -#endif - -/* Unlock LOCK. */ - -_EXTERN_INLINE void -__spin_unlock (__spin_lock_t *__lock) -{ - __asm__ __volatile__ ("mb; stq $31, %0; mb" - : "=m" (__lock)); -} - -/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */ - -_EXTERN_INLINE int -__spin_try_lock (register __spin_lock_t *__lock) -{ - register long int __rtn, __tmp; - - do - { - __asm__ __volatile__ ("mb; ldq_l %0,%1" /* Load lock value into TMP. */ - : "=r" (__tmp) : "m" (*__lock)); - __rtn = 2; /* Load locked value into RTN. */ - if (__tmp) - /* The lock is already taken. */ - return 0; - - /* The lock is not taken; try to get it now. */ - __asm__ __volatile__ ("stq_c %0,%1" - : "=r" (__rtn), "=m" (*__lock) - : "0" (__rtn), "1" (*__lock)); - /* RTN is clear if stq_c was interrupted; loop to try the lock again. */ - } while (! __rtn); - /* RTN is now nonzero; we have the lock. */ - return __rtn; -} - -/* Return nonzero if LOCK is locked. */ - -_EXTERN_INLINE int -__spin_lock_locked (__spin_lock_t *__lock) -{ - return *__lock != 0; -} - - -#endif /* machine-lock.h */ diff --git a/sysdeps/mach/alpha/machine-sp.h b/sysdeps/mach/alpha/machine-sp.h deleted file mode 100644 index e6df63c9ac..0000000000 --- a/sysdeps/mach/alpha/machine-sp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Machine-specific function to return the stack pointer. Alpha version. - Copyright (C) 1994, 1997, 2007 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _MACHINE_SP_H -#define _MACHINE_SP_H - -/* Return the current stack pointer. */ - -#ifndef _EXTERN_INLINE -#define _EXTERN_INLINE __extern_inline -#endif - -_EXTERN_INLINE void * -__thread_stack_pointer (void) -{ - register void *__sp__ __asm__ ("$30"); - return __sp__; -} - -#endif /* machine-sp.h */ diff --git a/sysdeps/mach/alpha/setfpucw.c b/sysdeps/mach/alpha/setfpucw.c deleted file mode 100644 index a2887c8dfb..0000000000 --- a/sysdeps/mach/alpha/setfpucw.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Set FP exception mask and rounding mode. Mach/Alpha version. - Copyright (C) 2002 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <fpu_control.h> - - -#define FPCR_DYN_SHIFT 58 /* first dynamic rounding mode bit */ -#define FPCR_DYN_CHOPPED (0x0UL << FPCR_DYN_SHIFT) /* towards 0 */ -#define FPCR_DYN_MINUS (0x1UL << FPCR_DYN_SHIFT) /* towards -INF */ -#define FPCR_DYN_NORMAL (0x2UL << FPCR_DYN_SHIFT) /* towards nearest */ -#define FPCR_DYN_PLUS (0x3UL << FPCR_DYN_SHIFT) /* towards +INF */ -#define FPCR_DYN_MASK (0x3UL << FPCR_DYN_SHIFT) - -static inline unsigned long -rdfpcr (void) -{ - unsigned long fpcr; - asm ("excb; mf_fpcr %0" : "=f"(fpcr)); - return fpcr; -} - -static inline void -wrfpcr (unsigned long fpcr) -{ - asm volatile ("mt_fpcr %0; excb" : : "f"(fpcr)); -} - - -void -__setfpucw (fpu_control_t fpu_control) -{ - unsigned long fpcr; - - if (!fpu_control) - fpu_control = _FPU_DEFAULT; - - /* first, set dynamic rounding mode: */ - - fpcr = rdfpcr(); - fpcr &= ~FPCR_DYN_MASK; - switch (fpu_control & 0xc00) - { - case _FPU_RC_NEAREST: fpcr |= FPCR_DYN_NORMAL; break; - case _FPU_RC_DOWN: fpcr |= FPCR_DYN_MINUS; break; - case _FPU_RC_UP: fpcr |= FPCR_DYN_PLUS; break; - case _FPU_RC_ZERO: fpcr |= FPCR_DYN_CHOPPED; break; - } - wrfpcr(fpcr); - - /* XXX trap bits? */ - - __fpu_control = fpu_control; /* update global copy */ -} diff --git a/sysdeps/mach/alpha/syscall.S b/sysdeps/mach/alpha/syscall.S deleted file mode 100644 index 15fc5b75b7..0000000000 --- a/sysdeps/mach/alpha/syscall.S +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (C) 1994,97,2002 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <sysdep.h> - -ENTRY (syscall) - mov a0, v0 /* Load system call number from first arg. */ - mov a1, a0 - mov a2, a1 - mov a3, a2 - mov a4, a3 - mov a5, a4 - /* Load the remaining possible args (up to 11) from the stack. */ - ldq a5,0(sp) - ldq t0,8(sp) - ldq t1,16(sp) - ldq t2,24(sp) - ldq t3,32(sp) - ldq t4,40(sp) - callsys - ret -END (syscall) diff --git a/sysdeps/mach/alpha/sysdep.h b/sysdeps/mach/alpha/sysdep.h deleted file mode 100644 index 84e21c8d5d..0000000000 --- a/sysdeps/mach/alpha/sysdep.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (C) 1994,97,2002 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#define MOVE(x,y) mov x, y - -#define LOSE asm volatile ("call_pal 0") /* halt */ - -#define START_MACHDEP \ - asm ("_start: mov $30, $16\n" /* Put initial SP in a0. */ \ - " br $27, 1f\n" /* Load GP from PC. */ \ - "1: ldgp $29, 0($27)\n" \ - " jmp $26, _start0"); /* Jump to _start0; don't return. */ -#define START_ARGS char **sparg -#define SNARF_ARGS(argc, argv, envp) \ - (envp = &(argv = &sparg[1])[(argc = *(int *) sparg) + 1]) - -#define CALL_WITH_SP(fn, sp) \ - ({ register long int __fn = (long int) fn, __sp = (long int) sp; \ - asm volatile ("mov %0,$30; jmp $31, (%1); ldgp $29, 0(%1)" \ - : : "r" (__sp), "r" (__fn)); }) - -#define STACK_GROWTH_DOWN - -#define RETURN_TO(sp, pc, retval) \ - asm volatile ("mov %0,$30; jmp $31, (%1); mov %2,$0" \ - : : "r" (sp), "r" (pc), "r" ((long int) (retval))); - -#define ALIGN 3 -#include <sysdeps/mach/sysdep.h> - -/* Alpha needs the .ent and .frame magic that the generic version lacks. */ -#undef ENTRY -#define ENTRY(name) \ - .globl name; \ - .align 3; \ - .ent name, 0; \ - name##: \ - .frame sp, 0, ra - -#include <mach/alpha/asm.h> -#undef at -#define at 28 -#define AT $28 -#define fp s6 diff --git a/sysdeps/mach/alpha/thread_state.h b/sysdeps/mach/alpha/thread_state.h deleted file mode 100644 index 0c9527bd26..0000000000 --- a/sysdeps/mach/alpha/thread_state.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Mach thread state definitions for machine-independent code. Alpha version. - Copyright (C) 1994, 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <mach/machine/thread_status.h> - -#define MACHINE_THREAD_STATE_FLAVOR ALPHA_THREAD_STATE -#define MACHINE_THREAD_STATE_COUNT ALPHA_THREAD_STATE_COUNT - -#define machine_thread_state alpha_thread_state - -#define PC pc -#define SP r30 -#define SYSRETURN r0 - -struct machine_thread_all_state - { - int set; /* Mask of bits (1 << FLAVOR). */ - struct alpha_thread_state basic; - struct alpha_exc_state exc; - struct alpha_float_state fpu; - }; - -#include <sysdeps/mach/thread_state.h> diff --git a/sysdeps/mach/hurd/alpha/bits/sigcontext.h b/sysdeps/mach/hurd/alpha/bits/sigcontext.h deleted file mode 100644 index 4f13a2c9b2..0000000000 --- a/sysdeps/mach/hurd/alpha/bits/sigcontext.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Machine-dependent signal context structure for GNU Hurd. Alpha version. - Copyright (C) 1994,97,2001 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H -# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead." -#endif - -#ifndef sc_alpha_thread_state - -/* Signal handlers are actually called: - void handler (int sig, int code, struct sigcontext *scp); */ - -/* State of this thread when the signal was taken. */ -struct sigcontext - { - /* These first members are machine-independent. */ - - long int sc_onstack; /* Nonzero if running on sigstack. */ - __sigset_t sc_mask; /* Blocked signals to restore. */ - - /* MiG reply port this thread is using. */ - unsigned long int sc_reply_port; - - /* Port this thread is doing an interruptible RPC on. */ - unsigned long int sc_intr_port; - - /* Error code associated with this signal (interpreted as `error_t'). */ - int sc_error; - - /* All following members are machine-dependent. The rest of this - structure is written to be laid out identically to: - { - struct alpha_thread_state basic; - struct alpha_exc_state exc; - struct alpha_float_state fpu; - } - trampoline.c knows this, so it must be changed if this changes. */ - -#define sc_alpha_thread_state sc_regs /* Beginning of correspondence. */ - long int sc_regs[31]; /* General registers $0..$30. */ - long int sc_pc; /* Program counter. */ - - /* struct alpha_exc_state */ -#define sc_alpha_exc_state sc_badvaddr - unsigned long int sc_badvaddr; - unsigned int sc_cause; /* Machine-level trap code. */ -#define SC_CAUSE_SET_SSTEP 1 - int sc_used_fpa; /* Nonzero if FPU was used. */ - - /* struct alpha_float_state - This is only filled in if sc_used_fpa is nonzero. */ -#define sc_alpha_float_state sc_fpregs - double sc_fpregs[31]; /* Floating point registers $f0..$f30. */ - long int sc_fpcsr; /* Floating point control/status register. */ - }; - -#endif /* sc_alpha_thread_state */ diff --git a/sysdeps/mach/hurd/alpha/exc2signal.c b/sysdeps/mach/hurd/alpha/exc2signal.c deleted file mode 100644 index 5f3fbbbbb1..0000000000 --- a/sysdeps/mach/hurd/alpha/exc2signal.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Translate Mach exception codes into signal numbers. Alpha version. - Copyright (C) 1994,97,2002 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <hurd.h> -#include <hurd/signal.h> -#include <mach/exception.h> - -/* Translate the Mach exception codes, as received in an `exception_raise' RPC, - into a signal number and signal subcode. */ - -void -_hurd_exception2signal (struct hurd_signal_detail *detail, int *signo) -{ - detail->error = 0; - - switch (detail->exc) - { - default: - *signo = SIGIOT; - detail->code = detail->exc; - break; - - case EXC_BAD_ACCESS: - if (detail->exc_code == KERN_PROTECTION_FAILURE) - *signo = SIGSEGV; - else - *signo = SIGBUS; - detail->code = detail->exc_subcode; - detail->error = detail->exc_code; - break; - - case EXC_BAD_INSTRUCTION: - *signo = SIGILL; - detail->code = detail->exc_code; - break; - - case EXC_ARITHMETIC: - *signo = SIGFPE; - detail->code = detail->exc_code; - break; - break; - - case EXC_EMULATION: - /* 3.0 doesn't give this one, why, I don't know. */ - *signo = SIGEMT; - detail->code = detail->exc_code; - break; - - case EXC_SOFTWARE: - *signo = SIGEMT; - detail->code = detail->exc_code; - break; - - case EXC_BREAKPOINT: - *signo = SIGTRAP; - detail->code = detail->exc_code; - break; - } -} diff --git a/sysdeps/mach/hurd/alpha/init-first.c b/sysdeps/mach/hurd/alpha/init-first.c deleted file mode 100644 index 6e55225890..0000000000 --- a/sysdeps/mach/hurd/alpha/init-first.c +++ /dev/null @@ -1,302 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. Alpha/Hurd. - Copyright (C) 1995,96,97,98,99,2000,01,02,03 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <assert.h> -#include <hurd.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <sysdep.h> -#include <set-hooks.h> -#include "hurdstartup.h" -#include "hurdmalloc.h" /* XXX */ - -extern void __mach_init (void); -extern void __init_misc (int, char **, char **); -#ifdef USE_NONOPTION_FLAGS -extern void __getopt_clean_environment (char **); -#endif -#ifndef SHARED -extern void _dl_non_dynamic_init (void) internal_function; -#endif -extern void __libc_global_ctors (void); - -unsigned int __hurd_threadvar_max; -unsigned long int __hurd_threadvar_stack_offset; -unsigned long int __hurd_threadvar_stack_mask; - -#ifndef SHARED -int __libc_enable_secure; -#endif -int __libc_multiple_libcs attribute_hidden = 1; - -extern int __libc_argc attribute_hidden; -extern char **__libc_argv attribute_hidden; -extern char **_dl_argv; - -void *(*_cthread_init_routine) (void); /* Returns new SP to use. */ -void (*_cthread_exit_routine) (int status) __attribute__ ((__noreturn__)); - -/* Things that want to be run before _hurd_init or much anything else. - Importantly, these are called before anything tries to use malloc. */ -DEFINE_HOOK (_hurd_preinit_hook, (void)); - - -/* We call this once the Hurd magic is all set up and we are ready to be a - Posixoid program. This does the same things the generic version does. */ -static void -posixland_init (int argc, char **argv, char **envp) -{ - __libc_argc = argc; - __libc_argv = argv; - __environ = envp; - -#ifndef SHARED - _dl_non_dynamic_init (); -#endif - __init_misc (argc, argv, envp); - -#ifdef USE_NONOPTION_FLAGS - /* This is a hack to make the special getopt in GNU libc working. */ - __getopt_clean_environment (envp); -#endif - -#ifdef SHARED - __libc_global_ctors (); -#endif -} - - -static void -init1 (intptr_t *data) -{ - int argc = (intptr_t) *data; - char **argv = (char **) &data[1]; - char **envp = &argv[argc + 1]; - struct hurd_startup_data *d; - - while (*envp) - ++envp; - d = (void *) ++envp; - - /* If we are the bootstrap task started by the kernel, - then after the environment pointers there is no Hurd - data block; the argument strings start there. */ - /* OSF Mach starts the bootstrap task with argc == 0. - XXX This fails if a non-bootstrap task gets started - with argc == 0. */ - if (argc && (void *) d != argv[0]) - { - _hurd_init_dtable = d->dtable; - _hurd_init_dtablesize = d->dtablesize; - - { - /* Check if the stack we are now on is different from - the one described by _hurd_stack_{base,size}. */ - - char dummy; - const vm_address_t newsp = (vm_address_t) &dummy; - - if (d->stack_size != 0 && (newsp < d->stack_base || - newsp - d->stack_base > d->stack_size)) - /* The new stack pointer does not intersect with the - stack the exec server set up for us, so free that stack. */ - __vm_deallocate (__mach_task_self (), d->stack_base, d->stack_size); - } - } - - if ((void *) d != argv[0] && (d->portarray || d->intarray)) - /* Initialize library data structures, start signal processing, etc. */ - _hurd_init (d->flags, argv, - d->portarray, d->portarraysize, - d->intarray, d->intarraysize); - -#ifndef SHARED - __libc_enable_secure = d->flags & EXEC_SECURE; -#endif -} - - -static inline void -init (intptr_t *data) -{ - int argc = *data; - char **argv = (void *) (data + 1); - char **envp = &argv[argc + 1]; - struct hurd_startup_data *d; - unsigned long int threadvars[_HURD_THREADVAR_MAX]; - - /* Provide temporary storage for thread-specific variables on the - startup stack so the cthreads initialization code can use them - for malloc et al, or so we can use malloc below for the real - threadvars array. */ - memset (threadvars, 0, sizeof threadvars); - __hurd_threadvar_stack_offset = (unsigned long int) threadvars; - - /* Since the cthreads initialization code uses malloc, and the - malloc initialization code needs to get at the environment, make - sure we can find it. We'll need to do this again later on since - switching stacks changes the location where the environment is - stored. */ - __environ = envp; - - while (*envp) - ++envp; - d = (void *) ++envp; - - /* The user might have defined a value for this, to get more variables. - Otherwise it will be zero on startup. We must make sure it is set - properly before before cthreads initialization, so cthreads can know - how much space to leave for thread variables. */ - if (__hurd_threadvar_max < _HURD_THREADVAR_MAX) - __hurd_threadvar_max = _HURD_THREADVAR_MAX; - - - /* After possibly switching stacks, call `init1' (above) with the user - code as the return address, and the argument data immediately above - that on the stack. */ - - if (_cthread_init_routine) - { - /* Initialize cthreads, which will allocate us a new stack to run on. */ - void *newsp = (*_cthread_init_routine) (); - struct hurd_startup_data *od; - - void switch_stacks (void); - - /* Copy per-thread variables from that temporary - area onto the new cthread stack. */ - memcpy (__hurd_threadvar_location_from_sp (0, newsp), - threadvars, sizeof threadvars); - - /* Copy the argdata from the old stack to the new one. */ - newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data, - (char *) d - (char *) data); - -#ifdef SHARED - /* And readjust the dynamic linker's idea of where the argument - vector lives. */ - assert (_dl_argv == argv); - _dl_argv = (void *) ((int *) newsp + 1); -#endif - - /* Set up the Hurd startup data block immediately following - the argument and environment pointers on the new stack. */ - od = (newsp + ((char *) d - (char *) data)); - if ((void *) argv[0] == d) - /* We were started up by the kernel with arguments on the stack. - There is no Hurd startup data, so zero the block. */ - memset (od, 0, sizeof *od); - else - /* Copy the Hurd startup data block to the new stack. */ - *od = *d; - - /* - Force NEWSP into sp and &init1 into pv, then branch to pv (call init1). - */ - asm volatile ("lda $30,0(%0); lda $27,0(%1); jsr $26,($27)" - : : "r" (newsp), "r" (&init1)); - } - else - { - /* We are not using cthreads, so we will have just a single allocated - area for the per-thread variables of the main user thread. */ - unsigned long int *array; - unsigned int i; - - array = malloc (__hurd_threadvar_max * sizeof (unsigned long int)); - if (array == NULL) - __libc_fatal ("Can't allocate single-threaded thread variables."); - - /* Copy per-thread variables from the temporary array into the - newly malloc'd space. */ - memcpy (array, threadvars, sizeof threadvars); - __hurd_threadvar_stack_offset = (unsigned long int) array; - for (i = _HURD_THREADVAR_MAX; i < __hurd_threadvar_max; ++i) - array[i] = 0; - - init1 (data); - } -} - - -/* Do the first essential initializations that must precede all else. */ -static inline void -first_init (void) -{ - /* Initialize data structures so we can do RPCs. */ - __mach_init (); - - RUN_HOOK (_hurd_preinit_hook, ()); -} - -#ifdef SHARED -/* This function is called specially by the dynamic linker to do early - initialization of the shared C library before normal initializers - expecting a Posixoid environment can run. It gets called with the - stack set up just as the user will see it, so it can switch stacks. */ - -void -_dl_init_first (intptr_t argc, ...) -{ - first_init (); - - init (&argc); -} -#endif - - -#ifdef SHARED -/* The regular posixland initialization is what goes into libc's - normal initializer. */ -/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT - pointer in the dynamic section based solely on that. It is convention - for this function to be in the `.init' section, but the symbol name is - the only thing that really matters!! */ -strong_alias (posixland_init, _init); - -void -__libc_init_first (int argc, char **argv, char **envp) -{ - /* Everything was done in the shared library initializer, _init. */ -} -#else -strong_alias (posixland_init, __libc_init_first); - - -void -_hurd_stack_setup (volatile intptr_t argc, ...) -{ - first_init (); - - _hurd_startup ((void **) &argc, &init); -} -#endif - - -/* This function is defined here so that if this file ever gets into - ld.so we will get a link error. Having this file silently included - in ld.so causes disaster, because the _init definition above will - cause ld.so to gain an init function, which is not a cool thing. */ - -void -_dl_start (void) -{ - abort (); -} diff --git a/sysdeps/mach/hurd/alpha/intr-msg.h b/sysdeps/mach/hurd/alpha/intr-msg.h deleted file mode 100644 index 4f172124e3..0000000000 --- a/sysdeps/mach/hurd/alpha/intr-msg.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Machine-dependent details of interruptible RPC messaging. Alpha version. - Copyright (C) 2002 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \ -({ \ - error_t err; \ - asm (".globl _hurd_intr_rpc_msg_do_trap\n" \ - ".globl _hurd_intr_rpc_msg_in_trap\n" \ - " mov %1, $16\n" \ - " mov %2, $17\n" \ - " mov %3, $18\n" \ - " mov %4, $19\n" \ - " mov %5, $20\n" \ - " mov %6, $21\n" \ - " mov %7, $1\n" \ - " lda $0, -25\n" \ - "_hurd_intr_rpc_msg_do_trap: callsys\n" \ - "_hurd_intr_rpc_msg_in_trap: ret\n" \ - : "=r" (err) \ - : "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \ - "r" (rcv_name), "r" (timeout), "r" (notify) \ - : "16", "17", "18", "19", "20", "21", "1", "0"); \ - err; \ -}) - -static void inline -INTR_MSG_BACK_OUT (struct alpha_thread_state *state) -{ - return; -} - -#include "hurdfault.h" - -/* This cannot be an inline function because it calls setjmp. */ -#define SYSCALL_EXAMINE(state, callno) \ -({ \ - u_int32_t *p = (void *) ((state)->pc - 4); \ - int result; \ - _hurdsig_catch_memory_fault (p) ? 0 : \ - ({ \ - result = (*p == 0x00000083); \ - _hurdsig_end_catch_fault (); \ - if (result) \ - /* The PC is just after a `callsys' instruction. \ - This is a system call in progress; v0 holds the call number. */ \ - *(callno) = (state)->r0; \ - result; \ - }); \ -}) - -struct mach_msg_trap_args - { - /* This is the order of arguments to mach_msg_trap. */ - mach_msg_header_t *msg; - mach_msg_option_t option; - mach_msg_size_t send_size; - mach_msg_size_t rcv_size; - mach_port_t rcv_name; - mach_msg_timeout_t timeout; - mach_port_t notify; - }; - -/* This cannot be an inline function because it calls setjmp. */ -#define MSG_EXAMINE(state, msgid, rcv_name, send_name, option, timeout) \ -({ \ - mach_msg_header_t *msg = (mach_msg_header_t *) (state)->r16; \ - *(option) = (mach_msg_option_t) (state)->r17; \ - *(rcv_name) = (mach_port_t) (state)->r18; \ - *(timeout) = (mach_msg_timeout_t) (state)->r19; \ - (msg == 0) ? \ - ({ \ - *(send_name) = MACH_PORT_NULL; \ - *(msgid) = 0; \ - 0; \ - }) : \ - (_hurdsig_catch_memory_fault (msg) ? -1 : \ - ({ \ - *(send_name) = msg->msgh_remote_port; \ - *(msgid) = msg->msgh_id; \ - _hurdsig_end_catch_fault (); \ - 0; \ - }) \ - ); \ -}) diff --git a/sysdeps/mach/hurd/alpha/longjmp-ts.c b/sysdeps/mach/hurd/alpha/longjmp-ts.c deleted file mode 100644 index f472dbcb30..0000000000 --- a/sysdeps/mach/hurd/alpha/longjmp-ts.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Perform a `longjmp' on a Mach thread_state. Alpha version. - Copyright (C) 2002, 2006 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <hurd/signal.h> -#include <setjmp.h> -#include <jmpbuf-offsets.h> -#include <mach/thread_status.h> - - -/* Set up STATE to do the equivalent of `longjmp (ENV, VAL);'. */ - -void -_hurd_longjmp_thread_state (void *state, jmp_buf env, int val) -{ - struct alpha_thread_state *const ts = state; - - ts->r9 = env[0].__jmpbuf[JB_S0]; - ts->r10 = env[0].__jmpbuf[JB_S1]; - ts->r11 = env[0].__jmpbuf[JB_S2]; - ts->r12 = env[0].__jmpbuf[JB_S3]; - ts->r13 = env[0].__jmpbuf[JB_S4]; - ts->r13 = env[0].__jmpbuf[JB_S5]; - ts->pc = env[0].__jmpbuf[JB_PC]; - ts->r15 = env[0].__jmpbuf[JB_FP]; - ts->r30 = env[0].__jmpbuf[JB_SP]; - ts->r0 = val ?: 1; - - /* XXX - To mimic longjmp we ought to restore some fp registers too. - But those registers are in struct alpha_float_state. - The only use of this is in fork, and it probably won't matter. - */ -} diff --git a/sysdeps/mach/hurd/alpha/sigreturn.c b/sysdeps/mach/hurd/alpha/sigreturn.c deleted file mode 100644 index 182d4cbd84..0000000000 --- a/sysdeps/mach/hurd/alpha/sigreturn.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Return from signal handler in GNU C library for Hurd. Alpha version. - Copyright (C) 1994,95,97,98,2002 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <hurd.h> -#include <hurd/signal.h> -#include <hurd/threadvar.h> -#include <hurd/msg.h> -#include <stdlib.h> -#include <string.h> - -int -__sigreturn (struct sigcontext *scp) -{ - struct hurd_sigstate *ss; - mach_port_t *reply_port; - - if (scp == NULL || (scp->sc_mask & _SIG_CANT_MASK)) - { - errno = EINVAL; - return -1; - } - - ss = _hurd_self_sigstate (); - __spin_lock (&ss->lock); - - /* Restore the set of blocked signals, and the intr_port slot. */ - ss->blocked = scp->sc_mask; - ss->intr_port = scp->sc_intr_port; - - /* Check for pending signals that were blocked by the old set. */ - if (ss->pending & ~ss->blocked) - { - /* There are pending signals that just became unblocked. Wake up the - signal thread to deliver them. But first, squirrel away SCP where - the signal thread will notice it if it runs another handler, and - arrange to have us called over again in the new reality. */ - ss->context = scp; - /* Clear the intr_port slot, since we are not in fact doing - an interruptible RPC right now. If SS->intr_port is not null, - the SCP context is doing an interruptible RPC, but the signal - thread will examine us while we are blocked in the sig_post RPC. */ - ss->intr_port = MACH_PORT_NULL; - __spin_unlock (&ss->lock); - __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); - /* If a pending signal was handled, sig_post never returned. */ - __spin_lock (&ss->lock); - } - - if (scp->sc_onstack) - { - ss->sigaltstack.ss_flags &= ~SS_ONSTACK; /* XXX threadvars */ - /* XXX cannot unlock until off sigstack */ - abort (); - } - else - __spin_unlock (&ss->lock); - - /* Destroy the MiG reply port used by the signal handler, and restore the - reply port in use by the thread when interrupted. */ - reply_port = - (mach_port_t *) __hurd_threadvar_location (_HURD_THREADVAR_MIG_REPLY); - if (*reply_port) - __mach_port_destroy (__mach_task_self (), *reply_port); - *reply_port = scp->sc_reply_port; - - if (scp->sc_used_fpa) - { - /* Restore FPU state. */ - - /* Restore the floating-point control/status register. - We must do this first because the compiler will need - a temporary FP register for the load. */ - asm volatile ("mt_fpcr %0" : : "f" (scp->sc_fpcsr)); - - /* Restore floating-point registers. */ -#define restore_fpr(n) \ - asm volatile ("ldt $f" #n ",%0" : : "m" (scp->sc_fpregs[n])) - restore_fpr (0); - restore_fpr (1); - restore_fpr (2); - restore_fpr (3); - restore_fpr (4); - restore_fpr (5); - restore_fpr (6); - restore_fpr (7); - restore_fpr (8); - restore_fpr (9); - restore_fpr (10); - restore_fpr (11); - restore_fpr (12); - restore_fpr (13); - restore_fpr (14); - restore_fpr (15); - restore_fpr (16); - restore_fpr (17); - restore_fpr (18); - restore_fpr (19); - restore_fpr (20); - restore_fpr (21); - restore_fpr (22); - restore_fpr (23); - restore_fpr (24); - restore_fpr (25); - restore_fpr (26); - restore_fpr (27); - restore_fpr (28); - restore_fpr (29); - restore_fpr (30); - } - - /* Load all the registers from the sigcontext. */ -#define restore_gpr(n) \ - asm volatile ("ldq $" #n ",%0" : : "m" (scpreg->sc_regs[n])) - - { - /* The `rei' PAL pseudo-instruction restores registers $2..$7, the PC - and processor status. So we can use these few registers for our - working variables. Unfortunately, it finds its data on the stack - and merely pops the SP ($30) over the words of state restored, - allowing no other option for the new SP value. So we must push the - registers and PSW it will to restore, onto the user's stack and let - it pop them from there. */ - register const struct sigcontext *const scpreg asm ("$2") = scp; - register integer_t *usp asm ("$3") = (integer_t *) scpreg->sc_regs[30]; - register integer_t usp_align asm ("$4"); - - /* Push an 8-word "trap frame" onto the user stack for `rei': - registers $2..$7, the PC, and the PSW. */ - - register struct rei_frame - { - integer_t regs[5], pc, ps; - } *rei_frame asm ("$5"); - - usp -= 8; - /* `rei' demands that the stack be aligned to a 64 byte (8 word) - boundary; bits 61..56 of the PSW are OR'd back into the SP value - after popping the 8-word trap frame, so we store (sp % 64) - there and this restores the original user SP. */ - usp_align = (integer_t) usp & 63L; - rei_frame = (void *) ((integer_t) usp & ~63L); - - /* Copy the registers and PC from the sigcontext. */ - memcpy (rei_frame->regs, &scpreg->sc_regs[2], sizeof rei_frame->regs); - rei_frame->pc = scpreg->sc_pc; - - /* Compute the new PS value to be restored. `rei' adds the value at - bits 61..56 to the SP to compensate for the alignment above that - cleared the low 6 bits; bits 5..3 are the new mode/privilege level - (must be >= current mode; 3 == user mode); bits 2..0 are "software", - unused by the processor or kernel (XXX should trampoline save these? - How?); in user mode, `rei' demands that all other bits be zero. */ - rei_frame->ps = (usp_align << 56) | (3 << 3); /* XXX low 3 bits??? */ - - /* Restore the other general registers: everything except $2..$7, which - are in the `rei' trap frame we set up above, and $30, which is the - SP which is popped by `rei'. */ - restore_gpr (1); - restore_gpr (8); - restore_gpr (9); - restore_gpr (10); - restore_gpr (11); - restore_gpr (12); - restore_gpr (13); - restore_gpr (14); - restore_gpr (15); - restore_gpr (16); - restore_gpr (17); - restore_gpr (18); - restore_gpr (19); - restore_gpr (20); - restore_gpr (21); - restore_gpr (22); - restore_gpr (23); - restore_gpr (24); - restore_gpr (25); - restore_gpr (26); - restore_gpr (27); - restore_gpr (28); - restore_gpr (29); - - /* Switch the stack pointer to the trap frame set up on - the user stack and do the magical `rei' PAL call. */ - asm volatile ("mov %0, $30\n" - "call_pal %1" - : : "r" (rei_frame), "i" (63)); /* PAL_rti */ - /* Firewall. */ - asm volatile ("halt"); - } - - /* NOTREACHED */ - return -1; -} - -weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/mach/hurd/alpha/static-start.S b/sysdeps/mach/hurd/alpha/static-start.S deleted file mode 100644 index a31d0d097a..0000000000 --- a/sysdeps/mach/hurd/alpha/static-start.S +++ /dev/null @@ -1,30 +0,0 @@ -/* Startup code for statically linked Hurd/Alpha binaries. - Copyright (C) 2002 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <sysdep.h> - - .text - .align 3 - .globl _start - .type _start,@function -_start: - jsr ra, _hurd_stack_setup - -#define _start _start1 -#include <sysdeps/alpha/elf/start.S> diff --git a/sysdeps/mach/hurd/alpha/trampoline.c b/sysdeps/mach/hurd/alpha/trampoline.c deleted file mode 100644 index 2360cbb469..0000000000 --- a/sysdeps/mach/hurd/alpha/trampoline.c +++ /dev/null @@ -1,249 +0,0 @@ -/* Set thread_state for sighandler, and sigcontext to recover. Alpha version. - Copyright (C) 1994,95,97,98,2002 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 Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <hurd/signal.h> -#include "thread_state.h" -#include "hurdfault.h" -#include <assert.h> - -struct mach_msg_trap_args - { - /* This is the order of arguments to mach_msg_trap. */ - mach_msg_header_t *msg; - mach_msg_option_t option; - mach_msg_size_t send_size; - mach_msg_size_t rcv_size; - mach_port_t rcv_name; - mach_msg_timeout_t timeout; - mach_port_t notify; - }; - - -struct sigcontext * -_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, - int signo, struct hurd_signal_detail *detail, - int rpc_wait, struct machine_thread_all_state *state) -{ - __label__ trampoline, rpc_wait_trampoline; - void *sigsp; - struct sigcontext *scp; - - if (ss->context) - { - /* We have a previous sigcontext that sigreturn was about - to restore when another signal arrived. We will just base - our setup on that. */ - if (! _hurdsig_catch_memory_fault (ss->context)) - { - memcpy (&state->basic, &ss->context->sc_alpha_thread_state, - sizeof (state->basic)); - memcpy (&state->exc, &ss->context->sc_alpha_exc_state, - sizeof (state->exc)); - state->set = (1 << ALPHA_THREAD_STATE) | (1 << ALPHA_EXC_STATE); - if (state->exc.used_fpa) - { - memcpy (&state->fpu, &ss->context->sc_alpha_float_state, - sizeof (state->fpu)); - state->set |= (1 << ALPHA_FLOAT_STATE); - } - assert (! rpc_wait); - /* The intr_port slot was cleared before sigreturn sent us the - sig_post that made us notice this pending signal, so - _hurd_internal_post_signal wouldn't do interrupt_operation. - After we return, our caller will set SCP->sc_intr_port (in the - new context) from SS->intr_port and clear SS->intr_port. Now - that we are restoring this old context recorded by sigreturn, - we want to restore its intr_port too; so store it in - SS->intr_port now, so it will end up in SCP->sc_intr_port - later. */ - ss->intr_port = ss->context->sc_intr_port; - } - _hurdsig_end_catch_fault (); - - /* If the sigreturn context was bogus, just ignore it. */ - ss->context = NULL; - } - else if (! machine_get_basic_state (ss->thread, state)) - return NULL; - - if ((ss->actions[signo].sa_flags & SA_ONSTACK) && - !(ss->sigaltstack.ss_flags & (SS_DISABLE|SS_ONSTACK))) - { - sigsp = ss->sigaltstack.ss_sp + ss->sigaltstack.ss_size; - ss->sigaltstack.ss_flags |= SS_ONSTACK; - /* XXX need to set up base of new stack for - per-thread variables, cthreads. */ - } - else - sigsp = (char *) state->basic.SP; - - /* Set up the sigcontext structure on the stack. This is all the stack - needs, since the args are passed in registers (below). */ - sigsp -= sizeof (*scp); - scp = sigsp; - - if (_hurdsig_catch_memory_fault (scp)) - { - /* We got a fault trying to write the stack frame. - We cannot set up the signal handler. - Returning NULL tells our caller, who will nuke us with a SIGILL. */ - return NULL; - } - else - { - /* Set up the sigcontext from the current state of the thread. */ - - scp->sc_onstack = ss->sigaltstack.ss_flags & SS_ONSTACK ? 1 : 0; - - /* struct sigcontext is laid out so that starting at sc_regs - mimics a struct alpha_thread_state. */ - memcpy (&scp->sc_alpha_thread_state, - &state->basic, sizeof (state->basic)); - - /* struct sigcontext is laid out so that starting at sc_badvaddr - mimics a struct mips_exc_state. */ - if (! machine_get_state (ss->thread, state, ALPHA_EXC_STATE, - &state->exc, &scp->sc_alpha_exc_state, - sizeof (state->exc))) - return NULL; - - if (state->exc.used_fpa && - /* struct sigcontext is laid out so that starting at sc_fpregs - mimics a struct alpha_float_state. This state - is only meaningful if the coprocessor was used. */ - ! machine_get_state (ss->thread, state, ALPHA_FLOAT_STATE, - &state->fpu, - &scp->sc_alpha_float_state, - sizeof (state->fpu))) - return NULL; - - _hurdsig_end_catch_fault (); - } - - /* Modify the thread state to call the trampoline code on the new stack. */ - if (rpc_wait) - { - /* The signalee thread was blocked in a mach_msg_trap system call, - still waiting for a reply. We will have it run the special - trampoline code which retries the message receive before running - the signal handler. - - To do this we change the OPTION argument in its registers to - enable only message reception, since the request message has - already been sent. */ - - /* The system call arguments are stored in consecutive registers - starting with a0 ($16). */ - struct mach_msg_trap_args *args = (void *) &state->basic.r16; - - assert (args->option & MACH_RCV_MSG); - /* Disable the message-send, since it has already completed. The - calls we retry need only wait to receive the reply message. */ - args->option &= ~MACH_SEND_MSG; - - /* Limit the time to receive the reply message, in case the server - claimed that `interrupt_operation' succeeded but in fact the RPC - is hung. */ - args->option |= MACH_RCV_TIMEOUT; - args->timeout = _hurd_interrupted_rpc_timeout; - - state->basic.pc = (long int) &&rpc_wait_trampoline; - /* After doing the message receive, the trampoline code will need to - update the v0 ($0) value to be restored by sigreturn. To simplify - the assembly code, we pass the address of its slot in SCP to the - trampoline code in at ($28). */ - state->basic.r28 = (long int) &scp->sc_regs[0]; - /* We must preserve the mach_msg_trap args in a0..a5 and t0 - ($16..$21, $1). Pass the handler args to the trampoline code in - t8..t10 ($22.$24). */ - state->basic.r22 = signo; - state->basic.r23 = detail->code; - state->basic.r24 = (long int) scp; - } - else - { - state->basic.pc = (long int) &&trampoline; - state->basic.r16 = signo; - state->basic.r17 = detail->code; - state->basic.r18 = (long int) scp; - } - - state->basic.r30 = (long int) sigsp; /* $30 is the stack pointer. */ - - /* We pass the handler function to the trampoline code in ra ($26). */ - state->basic.r26 = (long int) handler; - /* In the callee-saved register t12/pv ($27), we store the - address of __sigreturn itself, for the trampoline code to use. */ - state->basic.r27 = (long int) &__sigreturn; - /* In the callee-saved register t11/ai ($25), we save the SCP value to pass - to __sigreturn after the handler returns. */ - state->basic.r25 = (long int) scp; - - return scp; - - /* The trampoline code follows. This is not actually executed as part of - this function, it is just convenient to write it that way. */ - - rpc_wait_trampoline: - /* This is the entry point when we have an RPC reply message to receive - before running the handler. The MACH_MSG_SEND bit has already been - cleared in the OPTION argument in our registers. For our convenience, - at ($28) points to the sc_regs[0] member of the sigcontext (saved v0 - ($0)). */ - asm volatile - (/* Retry the interrupted mach_msg system call. */ - "lda $0, -25($31)\n" /* mach_msg_trap */ - "callsys\n" /* Magic system call instruction. */ - /* When the sigcontext was saved, v0 was MACH_RCV_INTERRUPTED. But - now the message receive has completed and the original caller of - the RPC (i.e. the code running when the signal arrived) needs to - see the final return value of the message receive in v0. So - store the new v0 value into the sc_regs[0] member of the sigcontext - (whose address is in at to make this code simpler). */ - "stq $0, 0($28)\n" - /* Since the argument registers needed to have the mach_msg_trap - arguments, we've stored the arguments to the handler function - in registers t8..t10 ($22..$24). */ - "mov $22, $16\n" - "mov $23, $17\n" - "mov $24, $18\n"); - - trampoline: - /* Entry point for running the handler normally. The arguments to the - handler function are already in the standard registers: - - a0 SIGNO - a1 SIGCODE - a2 SCP - - t12 also contains SCP; this value is callee-saved (and so should not get - clobbered by running the handler). We use this saved value to pass to - __sigreturn, so the handler can clobber the argument registers if it - likes. */ - /* Call the handler function, saving return address in ra ($26). */ - asm volatile ("jsr $26, ($26)"); - /* Reset gp ($29) from the return address (here) in ra ($26). */ - asm volatile ("ldgp $29, 0($26)"); - asm volatile ("mov $25, $16"); /* Move saved SCP to argument register. */ - /* Call __sigreturn (SCP); this cannot return. */ - asm volatile ("jmp $31, ($27)"); - - /* NOTREACHED */ - return NULL; -} |