diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | setjmp/Makefile | 2 | ||||
-rw-r--r-- | setjmp/bug269-setjmp.c | 107 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/__longjmp-common.S | 4 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/bsd-_setjmp.S | 3 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/setjmp-common.S | 5 |
6 files changed, 132 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog index f3451e0ffb..46a4c2b606 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2004-07-16 Steven Munroe <sjmunroe@us.ibm.com> + + [BZ #269] + * setjmp/Makefile (tests): Add bug269-setjmp. + * setjmp/bug269-setjmp.c: New file. + * sysdeps/powerpc/powerpc64/__longjmp-common.S [SHARED && !IS_IN_rtld]: + Store R2 from jmpbuf in callers TOC save area. + * sysdeps/powerpc/powerpc64/bsd-_setjmp.S [SHARED && !IS_IN_rtld]: + Store R2 in TOC save area. + * sysdeps/powerpc/powerpc64/setjmp-common.S [SHARED && !IS_IN_rtld]: + Copy TOC save area from previous frame as R2 (TOC) in jmpbuf. + 2004-07-16 Jakub Jelinek <jakub@redhat.com> * locale/newlocale.c: Include bits/libc-lock.h. diff --git a/setjmp/Makefile b/setjmp/Makefile index 4f33ae1b27..b94370d858 100644 --- a/setjmp/Makefile +++ b/setjmp/Makefile @@ -26,7 +26,7 @@ headers := setjmp.h bits/setjmp.h routines := setjmp sigjmp bsd-setjmp bsd-_setjmp \ longjmp __longjmp jmp-unwind -tests := tst-setjmp jmpbug +tests := tst-setjmp jmpbug bug269-setjmp include ../Rules diff --git a/setjmp/bug269-setjmp.c b/setjmp/bug269-setjmp.c new file mode 100644 index 0000000000..f50a5b1a58 --- /dev/null +++ b/setjmp/bug269-setjmp.c @@ -0,0 +1,107 @@ +/* Copyright (C) 2004 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. */ ; + +/* Test case for Bugzilla # 269 */ + +#include <stdio.h> +#include <setjmp.h> +#include <stdlib.h> + +jmp_buf buf1; +jmp_buf buf2; +int *p; +int n_x = 6; + +static int g_counter = 0; + +int +f (void) +{ + static int counter = 0; + static int way_point1 = 3; + static int way_point2 = 2; + int lose = 0; + + if (setjmp (buf1) != 101) + { + int a[n_x]; /* reallocate stack space */ + g_counter++; + p = &a[0]; + if (g_counter < 5) + longjmp (buf1, 2); + else if (g_counter == 5) + longjmp (buf1, 101); + else + { + _setjmp (buf2); + _longjmp (buf1, 101); + } + } + + way_point1--; + + if (counter == 0) + { + counter++; + { + int a[n_x]; /* reallocate stack space */ + g_counter++; + p = &a[0]; + if (g_counter < 5) + longjmp (buf1, 2); + else if (g_counter == 5) + longjmp (buf1, 101); + else + { + _setjmp (buf2); + _longjmp (buf1, 101); + } + } + } + + way_point2--; + + if (counter == 1) + { + counter++; + longjmp (buf2, 2); + } + + lose = !(way_point1 == 0 && way_point2 == 0 + && g_counter == 6 && counter == 2); + + return lose; +} + +static int +do_test (void) +{ + int lose; + + lose = f (); + + if (lose) + puts ("Test FAILED!"); + else + puts ("Test succeeded!"); + + return lose ? EXIT_FAILURE : EXIT_SUCCESS; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/sysdeps/powerpc/powerpc64/__longjmp-common.S b/sysdeps/powerpc/powerpc64/__longjmp-common.S index b6a2b79e55..b11a0fd7b5 100644 --- a/sysdeps/powerpc/powerpc64/__longjmp-common.S +++ b/sysdeps/powerpc/powerpc64/__longjmp-common.S @@ -112,6 +112,9 @@ no_vmx: ld r0,(JB_LR*8)(r3) ld r14,((JB_GPRS+0)*8)(r3) lfd fp14,((JB_FPRS+0)*8)(r3) +#if defined SHARED && !defined IS_IN_rtld + std r2,40(r1) /* Restore the callers TOC save area. */ +#endif ld r15,((JB_GPRS+1)*8)(r3) lfd fp15,((JB_FPRS+1)*8)(r3) ld r16,((JB_GPRS+2)*8)(r3) @@ -125,6 +128,7 @@ no_vmx: ld r20,((JB_GPRS+6)*8)(r3) lfd fp20,((JB_FPRS+6)*8)(r3) mtlr r0 +/* std r2,40(r1) Restore the TOC save area. */ ld r21,((JB_GPRS+7)*8)(r3) lfd fp21,((JB_FPRS+7)*8)(r3) ld r22,((JB_GPRS+8)*8)(r3) diff --git a/sysdeps/powerpc/powerpc64/bsd-_setjmp.S b/sysdeps/powerpc/powerpc64/bsd-_setjmp.S index e4428ecff7..13f4056706 100644 --- a/sysdeps/powerpc/powerpc64/bsd-_setjmp.S +++ b/sysdeps/powerpc/powerpc64/bsd-_setjmp.S @@ -47,6 +47,9 @@ default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4) as a libc_hidden_proto & is used in sysdeps/generic/libc-start.c if HAVE_CLEANUP_JMP_BUF is defined */ ENTRY (BP_SYM (__GI__setjmp)) +#if defined SHARED && !defined IS_IN_rtld + std r2,40(r1) /* Save the callers TOC in the save area. */ +#endif li r4,0 /* Set second argument to 0. */ b JUMPTARGET(BP_SYM (__vmx__sigsetjmp)) END (BP_SYM (__GI__setjmp)) diff --git a/sysdeps/powerpc/powerpc64/setjmp-common.S b/sysdeps/powerpc/powerpc64/setjmp-common.S index 99b181dfe4..ab57170875 100644 --- a/sysdeps/powerpc/powerpc64/setjmp-common.S +++ b/sysdeps/powerpc/powerpc64/setjmp-common.S @@ -44,7 +44,12 @@ ENTRY (BP_SYM (__sigsetjmp)) CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE) std r1,(JB_GPR1*8)(3) mflr r0 +#if defined SHARED && !defined IS_IN_rtld + ld r5,40(r1) /* Retrieve the callers TOC. */ + std r5,(JB_GPR2*8)(3) +#else std r2,(JB_GPR2*8)(3) +#endif std r14,((JB_GPRS+0)*8)(3) stfd fp14,((JB_FPRS+0)*8)(3) std r0,(JB_LR*8)(3) |