{make,set,swap}context broken on powerpc32
Jakub Jelinek
jakub@redhat.com
Tue Dec 19 16:23:00 GMT 2006
On Tue, Dec 19, 2006 at 04:48:09PM +1100, Paul Mackerras wrote:
> Steven Munroe writes:
>
> > >Note that sys_swapcontext can happily use, as its second argument, a
> > >ucontext where the uc_mcontext.uc_regs field is not 16-byte aligned,
> > >though, so glibc could work around the kernel bug by doing the memmove
> > >in makecontext as you suggest.
> > >
> > >
> > I would like to avoid any memmove by aligning the regs buffer properly
> > in the first place.
>
> I don't understand why makecontext has to set the regs pointer at all,
> given that the user has to call getcontext first. Why can't
> makecontext just use the pointer that getcontext has set?
>
> If you do that then there is no problem using the sys_swapcontext
> syscall even on kernels that have the alignment bug, as long as you
> use sys_swapcontext for setcontext and swapcontext. (And yes I will
> fix the alignment bug in the kernel.)
I completely agree, I also see no reason to align in
makecontext@@GLIBC_2.3.4. POSIX requires that the ucontext_t passed
to makecontext has been initialized by a getcontext call, and either
glibc is configured to use swapcontext syscall (in this case
the kernel should make sure it is aligned, but even if it does not,
we are using swapcontext syscall everywhere and the kernel doesn't
need it aligned), or we are not using swapcontext syscall anywhere
and getcontext@@GLIBC_2.3.4 pure userland implementation initializes
uc_mcontext.uc_regs to an aligned value.
Attached is a patch to change makecontext.c as well as a testcase
I posted just inline when starting this thread.
Jakub
-------------- next part --------------
2006-12-19 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
(__makecontext): Don't realign uc_mcontext.uc_regs.
--- libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S.jj 2006-01-07 04:51:11.000000000 +0100
+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S 2006-12-19 13:12:46.000000000 +0100
@@ -26,9 +26,7 @@
ENTRY(__makecontext)
/* Set up the first 7 args to the function in its registers */
- addi r11,r3,_UC_REG_SPACE+12
- clrrwi r11,r11,4
- stw r11,_UC_REGS_PTR(r3)
+ lwz r11,_UC_REGS_PTR(r3)
stw r6,_UC_GREGS+(PT_R3*4)(r11)
stw r7,_UC_GREGS+(PT_R4*4)(r11)
stw r8,_UC_GREGS+(PT_R5*4)(r11)
-------------- next part --------------
2006-12-19 Jakub Jelinek <jakub@redhat.com>
* stdlib/Makefile (tests): Add tst-makecontext.
* stdlib/tst-makecontext.c: New test.
--- libc/stdlib/Makefile.jj 2006-12-19 13:23:35.000000000 +0100
+++ libc/stdlib/Makefile 2006-12-19 13:24:27.000000000 +0100
@@ -67,7 +67,8 @@ tests := tst-strtol tst-strtod testmb t
tst-xpg-basename tst-random tst-random2 tst-bsearch \
tst-limits tst-rand48 bug-strtod tst-setcontext \
test-a64l tst-qsort tst-system testmb2 bug-strtod2 \
- tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2
+ tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
+ tst-makecontext
include ../Makeconfig
--- libc/stdlib/tst-makecontext.c.jj 2006-12-19 13:24:44.000000000 +0100
+++ libc/stdlib/tst-makecontext.c 2006-12-19 13:26:11.000000000 +0100
@@ -0,0 +1,57 @@
+/* Copyright (C) 2006 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ucontext.h>
+
+ucontext_t ucp;
+char st1[8192];
+__thread int thr;
+
+void
+cf (int i)
+{
+ if (i != 78 || thr != 94)
+ {
+ printf ("i %d thr %d\n", i, thr);
+ exit (1);
+ }
+ exit (0);
+}
+
+int
+main (void)
+{
+ if (getcontext (&ucp) != 0)
+ {
+ puts ("getcontext failed");
+ return 1;
+ }
+ thr = 94;
+ ucp.uc_link = NULL;
+ ucp.uc_stack.ss_sp = st1;
+ ucp.uc_stack.ss_size = sizeof st1;
+ makecontext (&ucp, (void (*) ()) cf, 1, 78);
+ if (setcontext (&ucp) != 0)
+ {
+ puts ("setcontext failed");
+ return 1;
+ }
+ return 2;
+}
More information about the Libc-alpha
mailing list