diff options
Diffstat (limited to 'sysdeps/mach/hurd/mips')
-rw-r--r-- | sysdeps/mach/hurd/mips/Dist | 3 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/bits/sigcontext.h | 80 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/dl-machine.c | 132 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/exc2signal.c | 97 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/init-fault.c | 41 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/init-first.c | 414 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/intr-msg.h | 127 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/longjmp-ctx.c | 41 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/longjmp-ts.c | 45 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/sigreturn.c | 223 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mips/trampoline.c | 292 |
11 files changed, 0 insertions, 1495 deletions
diff --git a/sysdeps/mach/hurd/mips/Dist b/sysdeps/mach/hurd/mips/Dist deleted file mode 100644 index b6f3ffa4c3..0000000000 --- a/sysdeps/mach/hurd/mips/Dist +++ /dev/null @@ -1,3 +0,0 @@ -longjmp-ctx.c -init-fault.c -dl-machine.c diff --git a/sysdeps/mach/hurd/mips/bits/sigcontext.h b/sysdeps/mach/hurd/mips/bits/sigcontext.h deleted file mode 100644 index 14c618857e..0000000000 --- a/sysdeps/mach/hurd/mips/bits/sigcontext.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Machine-dependent signal context structure for GNU Hurd. MIPS 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_mips_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. */ - - int sc_onstack; /* Nonzero if running on sigstack. */ - __sigset_t sc_mask; /* Blocked signals to restore. */ - - /* MiG reply port this thread is using. */ - unsigned int sc_reply_port; - - /* Port this thread is doing an interruptible RPC on. */ - unsigned 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 mips_thread_state ts; - struct mips_exc_state es; - struct mips_float_state fs; - } - trampoline.c knows this, so it must be changed if this changes. */ -#define sc_mips_thread_state sc_gpr /* Beginning of correspondence. */ - int sc_gpr[31]; /* "General" registers; [0] is r1. */ - int sc_mdlo, sc_mdhi; /* Low and high multiplication results. */ - int sc_pc; /* Instruction pointer. */ - - /* struct mips_exc_state */ -#define sc_mips_exc_state sc_cause - unsigned int sc_cause; /* Machine-level trap code. */ -#define SC_CAUSE_SST 0x00000044 - unsigned int sc_badvaddr; - unsigned int sc_coproc_used; /* Which coprocessors the thread has used. */ -#define SC_COPROC_USE_COP0 1 /* (by definition) */ -#define SC_COPROC_USE_COP1 2 /* FPA */ -#define SC_COPROC_USE_FPU SC_COPROC_USE_COP1 -#define SC_COPROC_USE_COP2 4 -#define SC_COPROC_USE_COP3 8 - - /* struct mips_float_state - This is only filled in if the SC_COPROC_USE_FPU bit - is set in sc_coproc_used. */ -#define sc_mips_float_state sc_fpr - int sc_fpr[32]; /* FP registers. */ - int sc_fpcsr; /* FPU status register. */ - int sc_fpeir; /* FP exception instruction register. */ - }; - -#endif /* sc_mips_thread_state */ diff --git a/sysdeps/mach/hurd/mips/dl-machine.c b/sysdeps/mach/hurd/mips/dl-machine.c deleted file mode 100644 index ce2d5db510..0000000000 --- a/sysdeps/mach/hurd/mips/dl-machine.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Operating system support for run-time dynamic linker. MIPS specific - stuffs on Hurd. - Copyright (C) 1996, 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 <hurd.h> -#include <link.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdlib.h> -#include <sys/mman.h> -#include <assert.h> -#include <sysdep.h> -#include <mach/mig_support.h> -#include "../stdio-common/_itoa.h" -#include <stdarg.h> -#include <ctype.h> -#include <sys/stat.h> -#include <libintl.h> - -void weak_function -abort (void) -{ - _exit (127); -} - - -#include <string.h> -#include <mach/error.h> -#include <errorlib.h> - -#undef _ -#define _(x) x - -/* Return a string describing the errno code in ERRNUM. */ -char * weak_function -_strerror_internal (int errnum, char *buf, size_t buflen) -{ - int system; - int sub; - int code; - const struct error_system *es; - extern void __mach_error_map_compat (int *); - - __mach_error_map_compat (&errnum); - - system = err_get_system (errnum); - sub = err_get_sub (errnum); - code = err_get_code (errnum); - - if (system > err_max_system || ! __mach_error_systems[system].bad_sub) - { - const char *unk = _("Error in unknown error system: "); - const size_t unklen = strlen (unk); - char *p = buf + buflen; - *--p = '\0'; - p = _itoa (errnum, p, 16, 1); - return memcpy (p - unklen, unk, unklen); - } - - es = &__mach_error_systems[system]; - - if (sub >= es->max_sub) - return (char *) es->bad_sub; - - if (code >= es->subsystem[sub].max_code) - { - const char *unk = _("Unknown error "); - const size_t unklen = strlen (unk); - char *p = buf + buflen; - size_t len = strlen (es->subsystem[sub].subsys_name); - *--p = '\0'; - p = _itoa (errnum, p, 16, 1); - *p-- = ' '; - p = memcpy (p - len, es->subsystem[sub].subsys_name, len); - return memcpy (p - unklen, unk, unklen); - } - - return (char *) _(es->subsystem[sub].codes[code]); -} - -/* Read the whole contents of FILE into new mmap'd space with given - protections. The size of the file is returned in SIZE. */ -void * -_dl_sysdep_read_whole_file (const char *file, size_t *size, int prot) -{ - struct stat stat; - mach_port_t memobj_rd; - void *contents; - error_t err; - - memobj_rd = __open (file, O_RDONLY, 0); - if (memobj_rd) - { - err = __io_stat ((file_t) memobj_rd, &stat); - if (err) - { - __hurd_fail (err); - contents = 0; - } - else - { - /* Map a copy of the file contents. */ - contents = __mmap (0, stat.st_size, prot, MAP_COPY, memobj_rd, 0); - if (contents == (void *)-1) - contents = 0; - else - *size = stat.st_size; - } - - __mach_port_deallocate (__mach_task_self (), memobj_rd); - } - else - contents = 0; - - return contents; -} diff --git a/sysdeps/mach/hurd/mips/exc2signal.c b/sysdeps/mach/hurd/mips/exc2signal.c deleted file mode 100644 index c505ae5b22..0000000000 --- a/sysdeps/mach/hurd/mips/exc2signal.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Translate Mach exception codes into signal numbers. MIPS version. - Copyright (C) 1996, 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 <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; - if (detail->exc_code == EXC_MIPS_II) - detail->code = detail->exc_subcode; - else - detail->code = 0; - break; - - case EXC_ARITHMETIC: - switch (detail->exc_code) - { - case EXC_MIPS_OV: /* integer overflow */ - *signo = SIGFPE; - detail->code = detail->exc_subcode; - break; - - default: - *signo = SIGFPE; - detail->code = 0; - break; - - case EXC_MIPS_INT: - /* Subcode is the fp_status word saved by the hardware. - Give an error code corresponding to the first bit set. */ - if (detail->exc_subcode == EXC_MIPS_FLT_UNIMP) - *signo = SIGILL; - else - *signo = SIGFPE; - detail->code = detail->exc_subcode; - break; - } - break; - - case EXC_EMULATION: - /* 3.0 doesn't give this one, why, I don't know. */ - *signo = SIGEMT; - detail->code = 0; - break; - - case EXC_SOFTWARE: - *signo = SIGEMT; - detail->code = 0; - break; - - case EXC_BREAKPOINT: - *signo = SIGTRAP; - detail->code = 0; - break; - } -} diff --git a/sysdeps/mach/hurd/mips/init-fault.c b/sysdeps/mach/hurd/mips/init-fault.c deleted file mode 100644 index 05f48a3a56..0000000000 --- a/sysdeps/mach/hurd/mips/init-fault.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Set up a thread_state for proc_handle_exceptions. MIPS version. - Copyright (C) 1996, 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 <hurd/signal.h> -#include <mach/thread_status.h> -#include <string.h> -#include <setjmp.h> - -extern jmp_buf _hurd_sigthread_fault_env; - -static char fault_stack[32]; -static volatile void -faulted (void) -{ - __longjmp (_hurd_sigthread_fault_env, 1); -} - -void -_hurd_initialize_fault_recovery_state (void *state) -{ - struct mips_thread_state *ts = state; - memset (ts, 0, sizeof (*ts)); - ts->r29 = (int) &fault_stack[sizeof (fault_stack)]; - ts->pc = (int) &faulted; -} diff --git a/sysdeps/mach/hurd/mips/init-first.c b/sysdeps/mach/hurd/mips/init-first.c deleted file mode 100644 index 6f53e839b3..0000000000 --- a/sysdeps/mach/hurd/mips/init-first.c +++ /dev/null @@ -1,414 +0,0 @@ -/* Initialization code run first thing by the ELF startup code. For Mips/Hurd. - Copyright (C) 1996,1997,1998,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 <hurd.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include "hurdstartup.h" -#include "set-hooks.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; - -int __libc_multiple_libcs attribute_hidden = 1; - -int __libc_argc attribute_hidden; -char **__libc_argv attribute_hidden; - -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)); - -static void -init1 (int argc, char *arg0, ...) -{ - char **argv = &arg0; - char **envp = &argv[argc + 1]; - struct hurd_startup_data *d; - - __libc_argc = argc; - __libc_argv = argv; - __environ = envp; - 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. */ - if ((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 (__hurd_threadvar_stack_mask == 0) - { - /* 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 i; - __hurd_threadvar_stack_offset - = (unsigned long int) malloc (__hurd_threadvar_max * - sizeof (unsigned long int)); - if (__hurd_threadvar_stack_offset == 0) - __libc_fatal ("Can't allocate single-threaded per-thread variables."); - for (i = 0; i < __hurd_threadvar_max; ++i) - ((unsigned long int *) __hurd_threadvar_stack_offset)[i] = 0; - } - - 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 - _dl_non_dynamic_init (); -#endif - __init_misc (argc, argv, __environ); - -#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 - - (void) &init1; -} - -static void * -__init (int *data) -{ - int argc = *data; - char **argv = (void *) (data + 1); - char **envp = &argv[argc + 1]; - struct hurd_startup_data *d; - - __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; - - /* Copy the argdata from the old stack to the new one. */ - newsp = memcpy (newsp - ((char *) &d[1] - (char *) data), data, - (char *) d - (char *) data); - - /* 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; - - /* Push the user code address on the top of the new stack. It will - be the return address for `init1'; we will jump there with NEWSP - as the stack pointer. */ - return newsp; - } - - /* The argument data is just above the stack frame we will unwind by - returning. */ - return (void *) data; - - (void) &__init; -} - -#ifdef SHARED -/* This function is called to initialize the shared C library. - It is called just before the user _start code from mips/elf/start.S, - with the stack set up as that code gets it. */ - -/* 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!! */ -/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/ - -#if __mips64 -asm ("\ - .section .init,\"ax\",@progbits\n\ - .align 3\n\ - .globl _init\n\ - .type _init,@function\n\ - .ent _init\n\ -_init:\n\ - .set noreorder\n\ - .cpload $25\n\ - .set reorder\n\ - dsubu $29, 8*8\n\ - .cprestore 6*8\n\ - sd $16, 4*8($29)\n\ - sd $31, 5*8($29)\n\ - jal preinit\n\ - sd $28, 6*8($29)\n\ - move $16, $29 # Save the old stack pointer to s0 ($16)\n\ - daddu $4, $29, 4*8\n\ - jal __init\n\ - # Restore saved registers from the old stack.\n\ - ld $28, 6*8($16)\n\ - ld $31, 5*8($16)\n\ - ld $16, 4*8($16)\n\ - move $29, $2 # set new sp to SP\n\ -call_init1:\n\ - ld $4, 0($29)\n\ - ld $5, 1*8($29)\n\ - ld $6, 2*8($29)\n\ - ld $7, 3*8($29)\n\ - dla $25, init1\n\ - jr $25\n\ - .end _init\n\ - .text\n\ -"); -#else -asm ("\ - .section .init,\"ax\",@progbits\n\ - .align 2\n\ - .globl _init\n\ - .type _init,@function\n\ - .ent _init\n\ -_init:\n\ - .set noreorder\n\ - .cpload $25\n\ - .set reorder\n\ - subu $29, 32\n\ - .cprestore 24\n\ - sw $16, 16($29)\n\ - sw $31, 20($29)\n\ - jal preinit\n\ - sw $28, 24($29)\n\ - move $16, $29 # Save the old stack pointer to s0 ($16)\n\ - addu $4, $29, 32\n\ - jal __init\n\ - # Restore saved registers from the old stack.\n\ - lw $28, 24($16)\n\ - lw $31, 20($16)\n\ - lw $16, 16($16)\n\ - move $29, $2 # set new sp to SP\n\ -call_init1:\n\ - lw $4, 0($29)\n\ - lw $5, 4($29)\n\ - lw $6, 8($29)\n\ - lw $7, 12($29)\n\ - la $25, init1\n\ - jr $25\n\ - .end _init\n\ - .text\n\ -"); -#endif - -static void -preinit (void) -{ - /* Initialize data structures so we can do RPCs. */ - __mach_init (); - - RUN_HOOK (_hurd_preinit_hook, ()); - - (void) &preinit; -} - -void __libc_init_first (int argc, ...) -{ -} -#endif - -#ifndef SHARED -/* An assembler code wrapping c function __init. */ -#ifdef __mips64 -asm ("\ - .text\n\ - .align 3\n\ -init:\n\ - dsubu $29, 8*8\n\ - sd $16, 4*8($29)\n\ - sd $31, 5*8($29)\n\ - move $16, $29\n\ - jal __init\n\ - ld $31, 5*8($16)\n\ - ld $16, 4*8($16)\n\ - move $29, $2 # set new sp to SP\n\ -call_init1:\n\ - ld $4, 0($29)\n\ - ld $5, 1*8($29)\n\ - ld $6, 2*8($29)\n\ - ld $7, 3*8($29)\n\ - dla $25, init1\n\ - jr $25\n\ -"); -#else -asm ("\ - .text\n\ - .align 2\n\ -init:\n\ - subu $29, 32\n\ - sw $16, 16($29)\n\ - sw $31, 20($29)\n\ - move $16, $29\n\ - jal __init\n\ - lw $31, 20($16)\n\ - lw $16, 16($16)\n\ - move $29, $2 # set new sp to SP\n\ -call_init1:\n\ - lw $4, 0($29)\n\ - lw $5, 4($29)\n\ - lw $6, 8($29)\n\ - lw $7, 12($29)\n\ - la $25, init1\n\ - jr $25\n\ -"); -#endif - -/* An assembler code wrapping c function ___libc_init_first. - ___libc_init_first does an RPC call to flush cache to put doinit - function on the stack, so we should call __mach_init first in - this wrap. */ -#ifdef __mips64 -asm ("\ - .text\n\ - .align 3\n\ - .globl __libc_init_first\n\ -__libc_init_first:\n\ - dsubu $29, 8\n\ - sd $31, 0($29)\n\ - jal __mach_init\n\ - ld $4, 0($29)\n\ - ld $5, 1*8($29)\n\ - ld $6, 2*8($29)\n\ - ld $7, 3*8($29)\n\ - j ___libc_init_first\n\ -"); -#else -asm ("\ - .text\n\ - .align 2\n\ - .globl __libc_init_first\n\ -__libc_init_first:\n\ - subu $29, 4\n\ - sw $31, 0($29)\n\ - jal __mach_init\n\ - lw $4, 0($29)\n\ - lw $5, 4($29)\n\ - lw $6, 8($29)\n\ - lw $7, 12($29)\n\ - j ___libc_init_first\n\ -"); -#endif - -static void -___libc_init_first (int return_addr, int argc, ...) -{ - void doinit (int *data) - { -#if 0 - /* This function gets called with the argument data at TOS. */ - void doinit1 (int argc, ...) - { - init (&argc); - } -#endif - extern void init (int *data); - - /* Push the user return address after the argument data, and then - jump to `doinit1' (above), so it is as if __libc_init_first's - caller had called `init' with the argument data already on the - stack. */ - *--data = return_addr; - -#ifdef __mips64 - asm volatile ("ld $31, 0(%0)\n" /* Load the original return address. */ - "daddu $29, %0, 8\n" /* Switch to new outermost stack. */ - "move $4, $29\n" - "jr %1" : : "r" (data), "r" (&init)); -#else - asm volatile ("lw $31, 0(%0)\n" /* Load the original return address. */ - "addu $29, %0, 4\n" /* Switch to new outermost stack. */ - "move $4, $29\n" - "jr %1" : : "r" (data), "r" (&init)); -#endif - /* NOTREACHED */ - } - -#if 0 - /* Initialize data structures so we can do RPCs. */ - __mach_init (); -#endif - - RUN_HOOK (_hurd_preinit_hook, ()); - - _hurd_startup ((void **) &argc, &doinit); - - (void) &___libc_init_first; -} -#endif diff --git a/sysdeps/mach/hurd/mips/intr-msg.h b/sysdeps/mach/hurd/mips/intr-msg.h deleted file mode 100644 index 16c78972ac..0000000000 --- a/sysdeps/mach/hurd/mips/intr-msg.h +++ /dev/null @@ -1,127 +0,0 @@ -/* Machine-dependent details of interruptible RPC messaging. Mips version. - Copyright (C) 1996, 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. */ - - -#ifdef __mips64 -#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \ -({ \ - error_t err; \ - mach_port_t __rcv_name = (rcv_name); \ - mach_msg_timeout_t __timeout = (timeout); \ - mach_port_t __notify = (notify); \ - asm (".globl _hurd_intr_rpc_msg_do_trap\n" \ - ".globl _hurd_intr_rpc_msg_in_trap\n" \ - " move $4, %1\n" \ - " move $5, %2\n" \ - " move $6, %3\n" \ - " move $7, %4\n" \ - " move $8, %5\n" \ - " move $9, %6\n" \ - " move $10, %7\n" \ - " dli $2, -25\n" \ - "_hurd_intr_rpc_msg_do_trap: syscall\n" \ - "_hurd_intr_rpc_msg_in_trap: move %0, $2\n" \ - : "=r" (err) \ - : "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \ - "r" (__rcv_name), "r" (__timeout), "r" (__notify) \ - : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", \ - "$11", "$12", "$13", "$14", "$15", "$24", "$25", "$28"); \ - err; \ -}) -#else -#define INTR_MSG_TRAP(msg, option, send_size, rcv_size, rcv_name, timeout, notify) \ -({ \ - error_t err; \ - mach_port_t __rcv_name = (rcv_name); \ - mach_msg_timeout_t __timeout = (timeout); \ - mach_port_t __notify = (notify); \ - asm (".globl _hurd_intr_rpc_msg_do_trap\n" \ - ".globl _hurd_intr_rpc_msg_in_trap\n" \ - " move $4, %1\n" \ - " move $5, %2\n" \ - " move $6, %3\n" \ - " move $7, %4\n" \ - " move $8, %5\n" \ - " move $9, %6\n" \ - " move $10, %7\n" \ - " li $2, -25\n" \ - "_hurd_intr_rpc_msg_do_trap: syscall\n" \ - "_hurd_intr_rpc_msg_in_trap: move %0, $2\n" \ - : "=r" (err) \ - : "r" (msg), "r" (option), "r" (send_size), "r" (rcv_size), \ - "r" (__rcv_name), "r" (__timeout), "r" (__notify) \ - : "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", \ - "$11", "$12", "$13", "$14", "$15", "$24", "$25", "$28"); \ - err; \ -}) -#endif - -static inline void -INTR_MSG_BACK_OUT (struct mips_thread_state *state) -{ - return; -} - -#include "hurdfault.h" - -static inline int -SYSCALL_EXAMINE (struct mips_thread_state *state, int *callno) -{ - u_int32_t *p = (void *) (state->pc - 4); - int result; - if (_hurdsig_catch_memory_fault (p)) - return 0; - if (result = (*p == 0x0000000c)) - /* The PC is just after a `syscall' instruction. - This is a system call in progress; v0($2) holds the call number. */ - *callno = state->r2; - _hurdsig_end_catch_fault (); - return 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; - }; - - -static inline mach_port_t -MSG_EXAMINE (struct mips_thread_state *state, int *msgid) -{ - mach_msg_header_t *msg; - mach_port_t send_port; - - msg = (mach_msg_header_t *) state->r4; - - if (_hurdsig_catch_memory_fault (msg)) - return MACH_PORT_NULL; - send_port = msg->msgh_remote_port; - *msgid = msg->msgh_id; - _hurdsig_end_catch_fault (); - - return send_port; -} diff --git a/sysdeps/mach/hurd/mips/longjmp-ctx.c b/sysdeps/mach/hurd/mips/longjmp-ctx.c deleted file mode 100644 index 66ee7b6fb8..0000000000 --- a/sysdeps/mach/hurd/mips/longjmp-ctx.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Perform a `longjmp' on a `struct sigcontext'. MIPS version. - Copyright (C) 1996, 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 <setjmp.h> -#include <hurd/signal.h> -#include <string.h> - -void -_hurd_longjmp_sigcontext (struct sigcontext *scp, jmp_buf env, int retval) -{ - scp->sc_gpr[16] = env[0].__regs[0]; - scp->sc_gpr[17] = env[0].__regs[1]; - scp->sc_gpr[18] = env[0].__regs[2]; - scp->sc_gpr[19] = env[0].__regs[3]; - scp->sc_gpr[20] = env[0].__regs[4]; - scp->sc_gpr[21] = env[0].__regs[5]; - scp->sc_gpr[22] = env[0].__regs[6]; - scp->sc_gpr[23] = env[0].__regs[7]; - - scp->sc_gpr[28] = (int) env[0].__gp; - scp->sc_fp = (int) env[0].__fp; - scp->sc_sp = (int) env[0].__sp; - scp->sc_pc = (int) env[0].__pc; - scp->sc_gpr[2] = retval ?: 1; -} diff --git a/sysdeps/mach/hurd/mips/longjmp-ts.c b/sysdeps/mach/hurd/mips/longjmp-ts.c deleted file mode 100644 index 4c69e4e2b9..0000000000 --- a/sysdeps/mach/hurd/mips/longjmp-ts.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Perform a `longjmp' on a Mach thread_state. MIPS version. - Copyright (C) 1996, 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 <hurd/signal.h> -#include <setjmp.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 mips_thread_state *ts = state; - - ts->r16 = env[0].__jmpbuf[0].__regs[0]; - ts->r17 = env[0].__jmpbuf[0].__regs[1]; - ts->r18 = env[0].__jmpbuf[0].__regs[2]; - ts->r19 = env[0].__jmpbuf[0].__regs[3]; - ts->r20 = env[0].__jmpbuf[0].__regs[4]; - ts->r21 = env[0].__jmpbuf[0].__regs[5]; - ts->r22 = env[0].__jmpbuf[0].__regs[6]; - ts->r23 = env[0].__jmpbuf[0].__regs[7]; - ts->r28 = (int) env[0].__jmpbuf[0].__gp; - ts->r29 = (int) env[0].__jmpbuf[0].__sp; - ts->r30 = (int) env[0].__jmpbuf[0].__fp; - ts->pc = (int) env[0].__jmpbuf[0].__pc; - ts->r2 = val ?: 1; -} diff --git a/sysdeps/mach/hurd/mips/sigreturn.c b/sysdeps/mach/hurd/mips/sigreturn.c deleted file mode 100644 index a9f7673eb5..0000000000 --- a/sysdeps/mach/hurd/mips/sigreturn.c +++ /dev/null @@ -1,223 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 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 <stdlib.h> -#include <mach/mips/mips_instruction.h> - -int -__sigreturn (struct sigcontext *scp) -{ - struct hurd_sigstate *ss; - struct hurd_userlink *link = (void *) &scp[1]; - 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); - - /* Remove the link on the `active resources' chain added by - _hurd_setup_sighandler. Its purpose was to make sure - that we got called; now we have, it is done. */ - _hurd_userlink_unlink (link); - - /* 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; - __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); - ss->context = NULL; - } - - 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_t port = *reply_port; - - /* Assigning MACH_PORT_DEAD here tells libc's mig_get_reply_port not to - get another reply port, but avoids mig_dealloc_reply_port trying to - deallocate it after the receive fails (which it will, because the - reply port will be bogus, whether we do this or not). */ - *reply_port = MACH_PORT_DEAD; - - __mach_port_destroy (__mach_task_self (), port); - } - *reply_port = scp->sc_reply_port; - - if (scp->sc_coproc_used & SC_COPROC_USE_FPU) - { - /* Restore FPU state. */ -#define restore_fpr(n) \ - asm volatile ("l.d $f" #n ",%0" : : "m" (scp->sc_fpr[n])) - - /* Restore floating-point registers. */ -#ifdef __mips64 - 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); - restore_fpr (31); -#else - restore_fpr (0); - restore_fpr (2); - restore_fpr (4); - restore_fpr (6); - restore_fpr (8); - restore_fpr (10); - restore_fpr (12); - restore_fpr (14); - restore_fpr (16); - restore_fpr (18); - restore_fpr (20); - restore_fpr (22); - restore_fpr (24); - restore_fpr (26); - restore_fpr (28); - restore_fpr (30); -#endif - - /* Restore the floating-point control/status register ($f31). */ - asm volatile ("ctc1 %0,$f31" : : "r" (scp->sc_fpcsr)); - } - - /* Load all the registers from the sigcontext. */ -#ifdef __mips64 -#define restore_gpr(n) \ - asm volatile ("ld $" #n ",%0" : : "m" (scpreg->sc_gpr[n - 1])) -#else -#define restore_gpr(n) \ - asm volatile ("lw $" #n ",%0" : : "m" (scpreg->sc_gpr[n - 1])) -#endif - - { - register const struct sigcontext *const scpreg asm ("$1") = scp; - register int *at asm ("$1"); - - /* First restore the multiplication result registers. The compiler - will use some temporary registers, so we do this before restoring - the general registers. */ - asm volatile ("mtlo %0" : : "r" (scpreg->sc_mdlo)); - asm volatile ("mthi %0" : : "r" (scpreg->sc_mdhi)); - - /* In the word after the saved PC, store the saved $1 value. */ - (&scpreg->sc_pc)[1] = scpreg->sc_gpr[0]; - - asm volatile (".set noreorder; .set noat;"); - - /* Restore the normal registers. */ - restore_gpr (2); - restore_gpr (3); - restore_gpr (4); - restore_gpr (5); - restore_gpr (6); - restore_gpr (7); - 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); - /* Registers 26-27 are kernel-only. */ - restore_gpr (28); - restore_gpr (29); /* Stack pointer. */ - restore_gpr (30); /* Frame pointer. */ - restore_gpr (31); /* Return address. */ - - at = &scpreg->sc_pc; - /* This is an emulated instruction that will find at the address in $1 - two words: the PC value to restore, and the $1 value to restore. */ - asm volatile (".word %0" : : "i" (op_sigreturn)); - asm volatile (".set reorder; .set at;"); - /* NOTREACHED */ - return at; /* To prevent optimization. */ - } - - /* NOTREACHED */ - return -1; -} - -weak_alias (__sigreturn, sigreturn) diff --git a/sysdeps/mach/hurd/mips/trampoline.c b/sysdeps/mach/hurd/mips/trampoline.c deleted file mode 100644 index dd42dfc1c6..0000000000 --- a/sysdeps/mach/hurd/mips/trampoline.c +++ /dev/null @@ -1,292 +0,0 @@ -/* Set thread_state for sighandler, and sigcontext to recover. MIPS version. - Copyright (C) 1996, 1997, 1998 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 <hurd/userlink.h> -#include "thread_state.h" -#include <assert.h> -#include <errno.h> -#include "hurdfault.h" -#include "intr-msg.h" - - -struct sigcontext * -_hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler, - int signo, struct hurd_signal_detail *detail, - volatile int rpc_wait, - struct machine_thread_all_state *state) -{ - __label__ trampoline, rpc_wait_trampoline, firewall; - void *volatile sigsp; - struct sigcontext *scp; - struct - { - int signo; - long int sigcode; - struct sigcontext *scp; /* Points to ctx, below. */ - void *sigreturn_addr; - void *sigreturn_returns_here; - struct sigcontext *return_scp; /* Same; arg to sigreturn. */ - struct sigcontext ctx; - struct hurd_userlink link; - } *stackframe; - - 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_mips_thread_state, - sizeof (state->basic)); - memcpy (&state->exc, &ss->context->sc_mips_exc_state, - sizeof (state->exc)); - state->set = (1 << MIPS_THREAD_STATE) | (1 << MIPS_EXC_STATE); - if (state->exc.coproc_state & SC_COPROC_USE_FPU) - { - memcpy (&state->fpu, &ss->context->sc_mips_float_state, - sizeof (state->fpu)); - state->set |= (1 << MIPS_FLOAT_STATE); - } - } - } - - if (! machine_get_basic_state (ss->thread, state)) - return NULL; - - /* Save the original SP in the gratuitous s0 ($16) slot. - We may need to reset the SP (the `r29' slot) to avoid clobbering an - interrupted RPC frame. */ - state->basic.r16 = state->basic.r29; - - 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.r29; - - /* Push the arguments to call `trampoline' on the stack. */ - sigsp -= sizeof (*stackframe); - stackframe = sigsp; - - if (_hurdsig_catch_memory_fault (stackframe)) - { - /* 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 - { - int ok; - - extern void _hurdsig_longjmp_from_handler (void *, jmp_buf, int); - - /* Add a link to the thread's active-resources list. We mark this as - the only user of the "resource", so the cleanup function will be - called by any longjmp which is unwinding past the signal frame. - The cleanup function (in sigunwind.c) will make sure that all the - appropriate cleanups done by sigreturn are taken care of. */ - stackframe->link.cleanup = &_hurdsig_longjmp_from_handler; - stackframe->link.cleanup_data = &stackframe->ctx; - stackframe->link.resource.next = NULL; - stackframe->link.resource.prevp = NULL; - stackframe->link.thread.next = ss->active_resources; - stackframe->link.thread.prevp = &ss->active_resources; - if (stackframe->link.thread.next) - stackframe->link.thread.next->thread.prevp - = &stackframe->link.thread.next; - ss->active_resources = &stackframe->link; - - /* Set up the arguments for the signal handler. */ - stackframe->signo = signo; - stackframe->sigcode = detail->code; - stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx; - stackframe->sigreturn_addr = &__sigreturn; - stackframe->sigreturn_returns_here = &&firewall; /* Crash on return. */ - - /* 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_gpr - mimics a struct mips_thread_state. */ - memcpy (&scp->sc_mips_thread_state, - &state->basic, sizeof (state->basic)); - - /* struct sigcontext is laid out so that starting at sc_cause - mimics a struct mips_exc_state. */ - ok = machine_get_state (ss->thread, state, MIPS_EXC_STATE, - &state->exc, &scp->sc_cause, - sizeof (state->exc)); - - if (ok && (scp->sc_coproc_used & SC_COPROC_USE_FPU)) - /* struct sigcontext is laid out so that starting at sc_fpr - mimics a struct mips_float_state. This state - is only meaningful if the coprocessor was used. */ - ok = machine_get_state (ss->thread, state, MIPS_FLOAT_STATE, - &state->fpu, &scp->sc_mips_float_state, - sizeof (state->fpu)); - - _hurdsig_end_catch_fault (); - - if (! ok) - return NULL; - } - - /* 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 ($4). */ - struct mach_msg_trap_args *args = (void *) &state->basic.r4; - - if (_hurdsig_catch_memory_fault (args)) - { - /* Faulted accessing ARGS. Bomb. */ - return NULL; - } - - 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; - - _hurdsig_end_catch_fault (); - - state->basic.pc = (int) &&rpc_wait_trampoline; - /* The reply-receiving trampoline code runs initially on the original - user stack. We pass it the signal stack pointer in s4 ($20). */ - state->basic.r29 = state->basic.r16; /* Restore mach_msg syscall SP. */ - state->basic.r20 = (int) sigsp; - /* After doing the message receive, the trampoline code will need to - update the v0 ($2) 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 s5 ($21). */ - state->basic.r21 = (int) &scp->sc_gpr[1]; - /* We must preserve the mach_msg_trap args in a0..t2 ($4..$10). - Pass the handler args to the trampoline code in s1..s3 ($17..$19). */ - state->basic.r17 = signo; - state->basic.r18 = detail->code; - state->basic.r19 = (int) scp; - } - else - { - state->basic.pc = (int) &&trampoline; - state->basic.r29 = (int) sigsp; - state->basic.r4 = signo; - state->basic.r5 = detail->code; - state->basic.r6 = (int) scp; - } - - /* We pass the handler function to the trampoline code in s6 ($22). */ - state->basic.r22 = (int) handler; - /* In the callee-saved register s0 ($16), we save the SCP value to pass - to __sigreturn after the handler returns. */ - state->basic.r16 = (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, - $3 points to the sc_gpr[1] member of the sigcontext (saved v0 ($2)). */ - asm volatile - (".set noat; .set noreorder; .set nomacro\n" - /* Retry the interrupted mach_msg system call. */ -#ifdef __mips64 - "dli $2, -25\n" /* mach_msg_trap */ -#else - "li $2, -25\n" /* mach_msg_trap */ -#endif - "syscall\n" - /* 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_gpr[1] member of the sigcontext - (whose address is in s5 to make this code simpler). */ -#ifdef __mips64 - "sd $2, ($21)\n" -#else - "sw $2, ($21)\n" -#endif - /* Since the argument registers needed to have the mach_msg_trap - arguments, we've stored the arguments to the handler function - in registers s1..s3 ($17..$19). */ - "move $4, $17\n" - "move $5, $18\n" - "move $6, $19\n" - /* Switch to the signal stack. */ - "move $29, $20\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 - */ - asm volatile - ("move $25, $22\n" /* Copy s6 to t9 for MIPS ABI. */ - "jal $25; nop\n" /* Call the handler function. */ - /* Call __sigreturn (SCP); this cannot return. */ -#ifdef __mips64 - "dla $1,%0\n" -#else - "la $1,%0\n" -#endif - "j $1\n" - "move $4, $16" /* Set up arg from saved SCP in delay slot. */ - : : "i" (&__sigreturn)); - - /* NOTREACHED */ - asm volatile (".set reorder; .set at; .set macro"); - - firewall: - asm volatile ("hlt: j hlt"); - - return NULL; -} |