From 60e8270d6ca19ddb351fb78e979ae908076e2d4b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 7 Nov 2012 21:00:09 -0800 Subject: [PATCH] Fix NULL ucontext->uc_link handling on sparc64. * sysdeps/unix/sysv/linux/sparc/sparc64/__start_context.S: New file. * sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c (__start_context): Declare. (__makecontext_ret): Delete. (__makecontext): Hook up __start_context instead of __makecontext_ret. * sysdeps/unix/sysv/linux/sparc/sparc64/Makefile (sysdep_routines): Add __start_context when in stdlib. --- ChangeLog | 11 +++++++ sysdeps/unix/sysv/linux/sparc/sparc64/Makefile | 4 +++ .../sysv/linux/sparc/sparc64/__start_context.S | 36 ++++++++++++++++++++++ .../unix/sysv/linux/sparc/sparc64/makecontext.c | 15 ++------- 4 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/__start_context.S diff --git a/ChangeLog b/ChangeLog index 3f7334d..bfccf93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2012-11-07 David S. Miller + + * sysdeps/unix/sysv/linux/sparc/sparc64/__start_context.S: New file. + * sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c + (__start_context): Declare. + (__makecontext_ret): Delete. + (__makecontext): Hook up __start_context instead of + __makecontext_ret. + * sysdeps/unix/sysv/linux/sparc/sparc64/Makefile + (sysdep_routines): Add __start_context when in stdlib. + 2012-11-07 Joseph Myers * sysdeps/x86/Makefile ($(objpfx)tst-xmmymm.out): Pass $(NM), diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc64/Makefile index 3e29dd8..715af3d 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 0000000..f1d1adc --- /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 + . */ + +#include + + .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 e925040..11e617e 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c @@ -21,6 +21,8 @@ #include #include +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) -- 2.7.4