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]

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


Hi,

if the uc_link field in ucontext is set to NULL the thread is supposed
to be exited after returning from the function specfied with
makecontext.  Doing this on s390 currently ends with a segfault when
trying to access fields of the ucontext given in uc_link.

With the attached patch exit is called if uc_link turns out to be
NULL.

Tested on s390 and s390x. No regressions.

I'll commit it after waiting a few days for comments.

Bye,

-Andreas-

2012-07-10  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.

---
 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 ---
 6 files changed, 89 insertions(+), 20 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,-1
+	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,-1
+	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.  */
+END(__makecontext_ret)


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