diff options
| author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2014-01-07 09:36:31 +0100 |
|---|---|---|
| committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2014-01-07 09:36:31 +0100 |
| commit | 93a45ff1ca6d459618bb0cf93580c4b2809a4b61 (patch) | |
| tree | 01ba50a65134ba45d974f63156617392dabfd430 | |
| parent | d5780febe69c2fe42d857e2feed54e9f4ba9ab87 (diff) | |
| download | glibc-93a45ff1ca6d459618bb0cf93580c4b2809a4b61.tar.xz glibc-93a45ff1ca6d459618bb0cf93580c4b2809a4b61.zip | |
S/390: Make jmp_buf extendible.
30 files changed, 762 insertions, 24 deletions
@@ -1,3 +1,47 @@ +2014-01-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> + + * Versions.def: Add GLIBC_2.19 for libpthread. + * nptl/sysdeps/unix/sysv/linux/s390/Versions: Add longjmp and + siglongjmp for libpthread with GLIBC_2.19 symver. + * nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c: New file. + * sysdeps/s390/Makefile: Build v1-longjmp.c and v1-sigjmp.c. + * sysdeps/s390/Versions: New GLIBC_2.19 and GLIBC_PRIVATE symbols. + * sysdeps/s390/__longjmp.c: New file. + * sysdeps/s390/bits/setjmp.h: Add new fields to __s390_jmp_buf. + * sysdeps/s390/longjmp.c: New file. + * sysdeps/s390/setjmp.S: New file. + * sysdeps/s390/sigjmp.S: New file. + * sysdeps/s390/v1-longjmp.c: New file. + * sysdeps/s390/v1-setjmp.h: New file. + * sysdeps/s390/v1-sigjmp.c: New file. + * sysdeps/unix/sysv/linux/s390/Makefile: Build __longjmp_chk. + * sysdeps/unix/sysv/linux/s390/Versions: Add __longjmp_chk with + GLIBC_2.19 version. + * sysdeps/unix/sysv/linux/s390/longjmp_chk.c: New file. + * sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c: Provide + versioned symbols for ____longjmp_chk. + * sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c: + Likewise. + * sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist: + Regenerate. + * sysdeps/unix/sysv/linux/s390/s390-32/nptl/libpthread.abilist: + Regenerate. + * sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist: + Regenerate. + * sysdeps/unix/sysv/linux/s390/s390-64/nptl/libpthread.abilist: + Regenerate. + * sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c: New file. + * sysdeps/s390/s390-32/__longjmp.c: Rename to ... + * sysdeps/s390/s390-32/__longjmp-common.c: ... this. + * sysdeps/s390/s390-32/setjmp.S: Rename and adjust to ... + * sysdeps/s390/s390-32/setjmp-common.S: ... this. + * sysdeps/s390/s390-64/__longjmp.c: Rename to ... + * sysdeps/s390/s390-64/__longjmp-common.c: ... this. + * sysdeps/s390/s390-64/setjmp.S: Rename and adjust to ... + * sysdeps/s390/s390-64/setjmp-common.S: ... this. + * sysdeps/s390/rtld-__longjmp.c: New file. + * sysdeps/s390/rtld-setjmp.S: New file. + 2014-01-06 Joseph Myers <joseph@codesourcery.com> [BZ #16400] diff --git a/Versions.def b/Versions.def index d834b10479..759c7542bf 100644 --- a/Versions.def +++ b/Versions.def @@ -106,6 +106,7 @@ libpthread { GLIBC_2.11 GLIBC_2.12 GLIBC_2.18 + GLIBC_2.19 GLIBC_PRIVATE } libresolv { diff --git a/nptl/sysdeps/unix/sysv/linux/s390/Versions b/nptl/sysdeps/unix/sysv/linux/s390/Versions new file mode 100644 index 0000000000..58632f467a --- /dev/null +++ b/nptl/sysdeps/unix/sysv/linux/s390/Versions @@ -0,0 +1,5 @@ +libpthread { + GLIBC_2.19 { + longjmp; siglongjmp; + } +} diff --git a/nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c b/nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c new file mode 100644 index 0000000000..801432cccb --- /dev/null +++ b/nptl/sysdeps/unix/sysv/linux/s390/pt-longjmp.c @@ -0,0 +1,63 @@ +/* Copyright (C) 2013 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/>. + + This is a copy of pthread/pt-longjmp.c made for extending the + jmpbuf structure on System z. */ + +#include <setjmp.h> +#include <stdlib.h> +#include <bits/wordsize.h> +#include "pthreadP.h" +#include <shlib-compat.h> +#if defined SHARED && SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_19) + +/* The __v1 version prototypes are declared in v1-setjmp.h which + cannot be included together with setjmp.h. So we put the + prototypes here manually. */ +extern void __v1__libc_siglongjmp (sigjmp_buf env, int val) + __attribute__ ((noreturn)); +extern void __v1__libc_longjmp (sigjmp_buf env, int val) + __attribute__ ((noreturn)); + +void __v1_siglongjmp (sigjmp_buf env, int val) +{ + __v1__libc_siglongjmp (env, val); +} + +void __v1_longjmp (jmp_buf env, int val) +{ + __v1__libc_longjmp (env, val); +} + +compat_symbol (libpthread, __v1_longjmp, longjmp, GLIBC_2_0); +compat_symbol (libpthread, __v1_siglongjmp, siglongjmp, GLIBC_2_0); +#endif /* defined SHARED && SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_19)) */ + +void +__v2_longjmp (jmp_buf env, int val) +{ + __libc_longjmp (env, val); +} + +void +__v2_siglongjmp (jmp_buf env, int val) +{ + __libc_siglongjmp (env, val); +} + +versioned_symbol (libpthread, __v2_longjmp, longjmp, GLIBC_2_19); +versioned_symbol (libpthread, __v2_siglongjmp, siglongjmp, GLIBC_2_19); diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile new file mode 100644 index 0000000000..fdc6ee50dc --- /dev/null +++ b/sysdeps/s390/Makefile @@ -0,0 +1,5 @@ +ifeq ($(subdir),setjmp) +ifeq (yes,$(build-shared)) +sysdep_routines += v1-longjmp v1-sigjmp +endif +endif diff --git a/sysdeps/s390/Versions b/sysdeps/s390/Versions index baf9842eeb..156abc79f4 100644 --- a/sysdeps/s390/Versions +++ b/sysdeps/s390/Versions @@ -1,3 +1,14 @@ +libc { + GLIBC_2.19 { + setjmp; _setjmp; __setjmp; __sigsetjmp; + longjmp; _longjmp; siglongjmp; + } + GLIBC_PRIVATE { + __v1__libc_longjmp; __v1__libc_siglongjmp; + __v2__libc_longjmp; __v2__libc_siglongjmp; + } +} + ld { GLIBC_2.3 { # runtime interface to TLS diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c new file mode 100644 index 0000000000..e4acd31c4a --- /dev/null +++ b/sysdeps/s390/__longjmp.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2013 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 <libc-symbols.h> +#include <shlib-compat.h> + +#define __longjmp __v2__longjmp +#include "__longjmp-common.c" +#undef __longjmp +strong_alias (__v2__longjmp, __longjmp) + +#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19) +# undef __longjmp +# define __V1_JMPBUF +# define __longjmp __v1__longjmp +# include "__longjmp-common.c" +#endif /* if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_19) */ diff --git a/sysdeps/s390/bits/setjmp.h b/sysdeps/s390/bits/setjmp.h index 0071a9dce5..25eaf10fdf 100644 --- a/sysdeps/s390/bits/setjmp.h +++ b/sysdeps/s390/bits/setjmp.h @@ -40,6 +40,10 @@ typedef struct __s390_jmp_buf /* We save fpu registers 4 and 6. */ long __fpregs[4]; # endif +#ifndef __V1_JMPBUF + unsigned long __flags; + char __reserved[128]; +#endif } __jmp_buf[1]; #endif diff --git a/sysdeps/s390/longjmp.c b/sysdeps/s390/longjmp.c new file mode 100644 index 0000000000..c758d149a4 --- /dev/null +++ b/sysdeps/s390/longjmp.c @@ -0,0 +1,64 @@ +/* Copyright (C) 2013 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/>. + + Versioned copy of sysdeps/generic/longjmp.c modified for extended + jmpbuf. */ + +#include <shlib-compat.h> +#include <stddef.h> +#include <setjmp.h> +#include <signal.h> + +extern void __v2__longjmp (__jmp_buf __env, int __val) + __attribute__ ((__noreturn__)); +extern void __v2__libc_longjmp (sigjmp_buf env, int val) + __attribute__ ((__noreturn__)); +libc_hidden_proto (__v2__libc_longjmp) + +/* Set the signal mask to the one specified in ENV, and jump + to the position specified in ENV, causing the setjmp + call there to return VAL, or 1 if VAL is 0. */ +void +__v2__libc_siglongjmp (sigjmp_buf env, int val) +{ + /* Perform any cleanups needed by the frames being unwound. */ + _longjmp_unwind (env, val); + + if (env[0].__mask_was_saved) + /* Restore the saved signal mask. */ + (void) __sigprocmask (SIG_SETMASK, &env[0].__saved_mask, + (sigset_t *) NULL); + + /* Call the machine-dependent function to restore machine state. */ + __v2__longjmp (env[0].__jmpbuf, val ?: 1); +} + +#ifndef __v2__longjmp +strong_alias (__v2__libc_siglongjmp, __v2__libc_longjmp) +libc_hidden_def (__v2__libc_longjmp) +weak_alias (__v2__libc_siglongjmp, __v2_longjmp) +weak_alias (__v2__libc_siglongjmp, __v2longjmp) +weak_alias (__v2__libc_siglongjmp, __v2siglongjmp) + +/* These will be used by libpthread only. */ +versioned_symbol (libc, __v2__libc_longjmp, __libc_longjmp, GLIBC_PRIVATE); +versioned_symbol (libc, __v2__libc_siglongjmp, __libc_siglongjmp, GLIBC_PRIVATE); + +versioned_symbol (libc, __v2_longjmp, _longjmp, GLIBC_2_19); +versioned_symbol (libc, __v2longjmp, longjmp, GLIBC_2_19); +versioned_symbol (libc, __v2siglongjmp, siglongjmp, GLIBC_2_19); +#endif /* ifndef __v2__longjmp */ diff --git a/sysdeps/s390/rtld-__longjmp.c b/sysdeps/s390/rtld-__longjmp.c new file mode 100644 index 0000000000..5e9f73981a --- /dev/null +++ b/sysdeps/s390/rtld-__longjmp.c @@ -0,0 +1,19 @@ +/* Copyright (C) 2013 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/>. */ + +/* Build a non-versioned object for rtld-*. */ +# include "__longjmp-common.c" diff --git a/sysdeps/s390/rtld-setjmp.S b/sysdeps/s390/rtld-setjmp.S new file mode 100644 index 0000000000..401101133b --- /dev/null +++ b/sysdeps/s390/rtld-setjmp.S @@ -0,0 +1,20 @@ +/* Extendible version of setjmp for System z + Copyright (C) 2013 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/>. */ + +/* Build a non-versioned object for rtld-*. */ +# include "setjmp-common.S" diff --git a/sysdeps/s390/s390-32/__longjmp.c b/sysdeps/s390/s390-32/__longjmp-common.c index 5d46e21923..f78ef656e5 100644 --- a/sysdeps/s390/s390-32/__longjmp.c +++ b/sysdeps/s390/s390-32/__longjmp-common.c @@ -25,7 +25,7 @@ /* Jump to the position specified by ENV, causing the setjmp call there to return VAL, or 1 if VAL is 0. */ -void +attribute_hidden void __longjmp (__jmp_buf env, int val) { #ifdef PTR_DEMANGLE diff --git a/sysdeps/s390/s390-32/setjmp.S b/sysdeps/s390/s390-32/setjmp-common.S index b8a0296b02..d7bb720454 100644 --- a/sysdeps/s390/s390-32/setjmp.S +++ b/sysdeps/s390/s390-32/setjmp-common.S @@ -27,24 +27,24 @@ ENTRY (setjmp) .weak C_SYMBOL_NAME (setjmp) lhi %r3,1 /* second argument of one */ - j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */ + j 0f /* branch relativ to __sigsetjmp */ END (setjmp) /* Binary compatibility entry point. */ ENTRY(_setjmp) .weak C_SYMBOL_NAME (_setjmp) lhi %r3,0 /* second argument of zero */ - j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */ + j 0f /* branch relativ to __sigsetjmp */ END (_setjmp) libc_hidden_def (_setjmp) ENTRY(__setjmp) lhi %r3,0 /* second argument of zero */ - j .Linternal_sigsetjmp /* branch relativ to __sigsetjmp */ + j 0f /* branch relativ to __sigsetjmp */ END (__setjmp) ENTRY(__sigsetjmp) -.Linternal_sigsetjmp: +0: #ifdef PTR_MANGLE stm %r6,%r13,0(%r2) /* store registers in jmp_buf */ lr %r4,%r14 @@ -55,6 +55,10 @@ ENTRY(__sigsetjmp) #else stm %r6,%r15,0(%r2) /* store registers in jmp_buf */ #endif +#ifndef __V1_JMPBUF + lhi %r4,0 + st %r4,56(%r2) /* Set __flags to 0. */ +#endif std %f4,40(%r2) std %f6,48(%r2) #if defined NOT_IN_libc && defined IS_IN_rtld @@ -66,15 +70,15 @@ ENTRY(__sigsetjmp) we can't save and restore our caller's value. Instead, we do an indirect jump through the GOT. */ basr %r1,0 -.L0: al %r1,.L1 - .L0(0,%r1) /* get address of global offset table */ - /* get address of __sigjmp_save from got */ +0: al %r1,1f-0b(0,%r1) /* get address of global offset table */ + /* get address of __sigjmp_save from got */ l %r1,__sigjmp_save@GOT12(0,%r1) br %r1 -.L1: .long _GLOBAL_OFFSET_TABLE_ - .L0 +1: .long _GLOBAL_OFFSET_TABLE_ - 0b #else basr %r1,0 -.L0: l %r1,.L1-.L0(0,%r1) /* load address of __sigjmp_save */ - br %r1 /* tail-call __sigjmp_save */ -.L1: .long __sigjmp_save +0: l %r1,1f-0b(0,%r1) /* load address of __sigjmp_save */ + br %r1 /* tail-call __sigjmp_save */ +1: .long __sigjmp_save #endif END (__sigsetjmp) diff --git a/sysdeps/s390/s390-64/__longjmp.c b/sysdeps/s390/s390-64/__longjmp-common.c index 168ebf562b..46cabb67bc 100644 --- a/sysdeps/s390/s390-64/__longjmp.c +++ b/sysdeps/s390/s390-64/__longjmp-common.c @@ -25,7 +25,7 @@ /* Jump to the position specified by ENV, causing the setjmp call there to return VAL, or 1 if VAL is 0. */ -void +attribute_hidden void __longjmp |
