Fix NULL ucontext->uc_link handling on sparc64.
authorDavid S. Miller <davem@davemloft.net>
Thu, 8 Nov 2012 05:00:09 +0000 (21:00 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 8 Nov 2012 05:01:06 +0000 (21:01 -0800)
* 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
sysdeps/unix/sysv/linux/sparc/sparc64/Makefile
sysdeps/unix/sysv/linux/sparc/sparc64/__start_context.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c

index 3f7334dc6cd1512750d9ff6bd2e6ec712e4caf1a..bfccf931bebdc3a67c0df5a79266d8c70668d5ac 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-11-07  David S. Miller  <davem@davemloft.net>
+
+       * 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  <joseph@codesourcery.com>
 
        * sysdeps/x86/Makefile ($(objpfx)tst-xmmymm.out): Pass $(NM),
index 3e29dd84132c2c5ed14a51ee3d51dfbda41a674c..715af3df7b14857f760f02a46a27d59a1d4f0c2e 100644 (file)
@@ -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 (file)
index 0000000..f1d1adc
--- /dev/null
@@ -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)
index e925040d14ad2cd3ca3d3226477e39787a9a116b..11e617e03b8a30cfc15ff1371404c56baf650569 100644 (file)
@@ -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)