diff options
Diffstat (limited to 'sysdeps/unix')
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc64/Makefile | 4 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc64/__start_context.S | 36 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c | 15 |
3 files changed, 43 insertions, 12 deletions
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile index 3e29dd8413..715af3df7b 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile @@ -3,3 +3,7 @@ default-abi := 64 sysdep-CFLAGS += -fcall-used-g6 LD += -melf64_sparc + +ifeq ($(subdir),stdlib) +sysdep_routines += __start_context +endif diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/__start_context.S b/sysdeps/unix/sysv/linux/sparc/sparc64/__start_context.S new file mode 100644 index 0000000000..f1d1adc862 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/__start_context.S @@ -0,0 +1,36 @@ +/* Copyright (C) 2012 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, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + + .text + +/* This is the helper code which gets called if a function which is + registered with 'makecontext' returns. In this case we have to + install the context listed in the uc_link element of the context + 'makecontext' manipulated at the time of the 'makecontext' call. + If the pointer is NULL the process must terminate. */ + +ENTRY(__start_context) + brz,pn %i0, 1f + mov 1, %o1 + call __setcontext + mov %i0, %o0 +1: call HIDDEN_JUMPTARGET(exit) + mov 0, %o0 + unimp 0 +END(__start_context) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c b/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c index e925040d14..11e617e03b 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c @@ -21,6 +21,8 @@ #include <stdlib.h> #include <ucontext.h> +extern void __start_context (struct ucontext *ucp); + void __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) { @@ -37,7 +39,7 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) ucp->uc_mcontext.mc_gregs[MC_PC] = (long) func; ucp->uc_mcontext.mc_gregs[MC_NPC] = ((long) func) + 4; ucp->uc_mcontext.mc_gregs[MC_O6] = ((long) sp) - 0x7ff; - ucp->uc_mcontext.mc_gregs[MC_O7] = ((long) __makecontext_ret) - 8; + ucp->uc_mcontext.mc_gregs[MC_O7] = ((long) __start_context) - 8; ucp->uc_mcontext.mc_fp = ((long) topsp) - 0x7ff; ucp->uc_mcontext.mc_i7 = 0; topsp[14] = 0; @@ -52,15 +54,4 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) va_end (ap); } -asm (" \n\ - .text \n\ - .type __makecontext_ret, #function \n\ -__makecontext_ret: \n\ - mov 1, %o1 \n\ - call __setcontext \n\ - mov %i0, %o0 \n\ - unimp 0 \n\ - .size __makecontext_ret, .-__makecontext_ret \n\ - "); - weak_alias (__makecontext, makecontext) |