This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] S/390: Fix makecontext with uc_link == NULL


> Do we have a testcase that covers this failure?
> 
> If we don't, could you try to work one up?

stdlib/tst-makecontext already calls makecontext with uc_link == NULL
but the function invoked in the context does explicitly call exit (0).
Removing this enables the testcase to cover that problem as well.

I've added this to my patch.

Bye,

-Andreas-


2012-07-12  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c: Move
	__makecontext_ret to ...
	* sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S:
	... here and call exit if uc_link is NULL.  New file.
	* sysdeps/unix/sysv/linux/s390/s390-32/Makefile: Add
	__makecontext_ret.S.
	* sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c: Move
	__makecontext_ret to ...
	* sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S:
	... here and call exit if uc_link is NULL.  New file.
	* sysdeps/unix/sysv/linux/s390/s390-64/Makefile: Add
	__makecontext_ret.S.
	* stdlib/tst-makecontext.c: Remove explicit exit call.

---
 stdlib/tst-makecontext.c                                 |    3 
 sysdeps/unix/sysv/linux/s390/s390-32/Makefile            |    4 +
 sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S |   48 +++++++++++++++
 sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c       |   12 ---
 sysdeps/unix/sysv/linux/s390/s390-64/Makefile            |    4 +
 sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S |   29 +++++++++
 sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c       |   12 ---
 7 files changed, 91 insertions(+), 21 deletions(-)

Index: glibc/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c
===================================================================
--- glibc.orig/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c
+++ glibc/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c
@@ -80,10 +80,10 @@ __makecontext (ucontext_t *ucp, void (*f
   sp -= 24;
   *sp = 0;
 
-  /* Pass (*func) to __start_context in %r7.  */
+  /* Pass (*func) to __makecontext_ret in %r7.  */
   ucp->uc_mcontext.gregs[7] = (long int) func;
 
-  /* Pass ucp->uc_link to __start_context in %r8.  */
+  /* Pass ucp->uc_link to __makecontext_ret in %r8.  */
   ucp->uc_mcontext.gregs[8] = (long int) ucp->uc_link;
 
   /* Pass address of setcontext in %r9.  */
@@ -93,12 +93,4 @@ __makecontext (ucontext_t *ucp, void (*f
   ucp->uc_mcontext.gregs[15] = (long int) sp;
 }
 
-asm (".text\n"
-     ".type __makecontext_ret,@function\n"
-     "__makecontext_ret:\n"
-     "      basr  %r14,%r7\n"
-     "      lr    %r2,%r8\n"
-     "      br    %r9\n"
-     ".size __makecontext_ret, .-__makecontext_ret");
-
 weak_alias (__makecontext, makecontext)
Index: glibc/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
===================================================================
--- /dev/null
+++ glibc/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
@@ -0,0 +1,29 @@
+/* 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>
+
+ENTRY(__makecontext_ret)
+	basr	%r14,%r7
+	ltgr	%r8,%r8			/* Check whether uc_link is 0.  */
+	jz	1f
+	lgr	%r2,%r8
+	br	%r9
+1:	lghi	%r2,0
+	brasl	%r14,HIDDEN_JUMPTARGET (exit)
+	j	.+2			/* Trap if exit returns.  */
+END(__makecontext_ret)
Index: glibc/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
===================================================================
--- glibc.orig/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
+++ glibc/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c
@@ -80,10 +80,10 @@ __makecontext (ucontext_t *ucp, void (*f
   sp -= 20;
   *sp = 0;
 
-  /* Pass (*func) to __start_context in %r7.  */
+  /* Pass (*func) to __makecontext_ret in %r7.  */
   ucp->uc_mcontext.gregs[7] = (long int) func;
 
-  /* Pass ucp->uc_link to __start_context in %r8.  */
+  /* Pass ucp->uc_link to __makecontext_ret in %r8.  */
   ucp->uc_mcontext.gregs[8] = (long int) ucp->uc_link;
 
   /* Pass address of setcontext in %r9.  */
@@ -93,12 +93,4 @@ __makecontext (ucontext_t *ucp, void (*f
   ucp->uc_mcontext.gregs[15] = (long int) sp;
 }
 
-asm (".text\n"
-     ".type __makecontext_ret,@function\n"
-     "__makecontext_ret:\n"
-     "      basr  %r14,%r7\n"
-     "      lgr   %r2,%r8\n"
-     "      br    %r9\n"
-     ".size __makecontext_ret, .-__makecontext_ret");
-
 weak_alias (__makecontext, makecontext)
Index: glibc/sysdeps/unix/sysv/linux/s390/s390-64/Makefile
===================================================================
--- glibc.orig/sysdeps/unix/sysv/linux/s390/s390-64/Makefile
+++ glibc/sysdeps/unix/sysv/linux/s390/s390-64/Makefile
@@ -12,3 +12,7 @@ sysdep_routines += framestate
 shared-only-routines += framestate
 endif
 endif
+
+ifeq ($(subdir),stdlib)
+sysdep_routines += __makecontext_ret
+endif
Index: glibc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile
===================================================================
--- glibc.orig/sysdeps/unix/sysv/linux/s390/s390-32/Makefile
+++ glibc/sysdeps/unix/sysv/linux/s390/s390-32/Makefile
@@ -21,3 +21,7 @@ sysdep_routines += framestate
 shared-only-routines += framestate
 endif
 endif
+
+ifeq ($(subdir),stdlib)
+sysdep_routines += __makecontext_ret
+endif
Index: glibc/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
===================================================================
--- /dev/null
+++ glibc/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
@@ -0,0 +1,48 @@
+/* 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>
+
+ENTRY(__makecontext_ret)
+	basr  %r14,%r7
+	ltr   %r8,%r8			/* Check whether uc_link is 0.  */
+	jz    1f
+	lr    %r2,%r8
+	br    %r9
+1:	lhi   %r2,0			/* EXIT return value.  */
+	basr	%r13,0
+2:
+#ifdef PIC
+	l       %r12,4f-2b(%r13)
+	la      %r12,0(%r12,%r13)	/* GOT pointer in r12 after this.  */
+	l       %r1,3f-2b(%r13)
+	bas     %r14,0(%r1,%r12)
+	.align  4
+3:
+	.long   HIDDEN_JUMPTARGET (exit)@GOTOFF
+4:
+	.long   _GLOBAL_OFFSET_TABLE_-2b
+#else
+	l	%r1,3f-2b(%r13)
+	basr	%r14,%r1
+	.align  4
+3:
+	.long   HIDDEN_JUMPTARGET (exit)
+#endif
+	.align	2
+	j	.+2			/* Trap if exit returns for some reason.  */
+END(__makecontext_ret)
Index: glibc/stdlib/tst-makecontext.c
===================================================================
--- glibc.orig/stdlib/tst-makecontext.c
+++ glibc/stdlib/tst-makecontext.c
@@ -35,7 +35,8 @@ cf (int i)
       printf ("i %d thr %d\n", i, thr);
       exit (1);
     }
-  exit (0);
+  /* Since uc_link below has been set to NULL setcontext is supposed
+     to end the thread after this function returns.  */
 }
 
 int


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]