This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] S/390: Fix makecontext with uc_link == NULL
- From: "Andreas Krebbel" <krebbel at linux dot vnet dot ibm dot com>
- To: "Carlos O'Donell" <carlos at codesourcery dot com>
- Cc: libc-alpha at sourceware dot org
- Date: Thu, 12 Jul 2012 14:19:08 +0200
- Subject: Re: [PATCH] S/390: Fix makecontext with uc_link == NULL
- References: <20120710102022.GA5123@bart><4FFC2AA3.50908@codesourcery.com>
> 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