summaryrefslogtreecommitdiff
path: root/libc/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/unix/sysv/linux')
-rw-r--r--libc/sysdeps/unix/sysv/linux/configure3
-rw-r--r--libc/sysdeps/unix/sysv/linux/configure.ac2
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c27
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h2
-rw-r--r--libc/sysdeps/unix/sysv/linux/powerpc/time.c27
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/Makefile6
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/Versions4
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/getcontext.S38
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/longjmp_chk.c44
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/rtld-getcontext.S19
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c24
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext-common.S (renamed from libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S)41
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist11
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libpthread.abilist4
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S12
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S27
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/sys/ucontext.h96
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-32/ucontext_i.sym26
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c25
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext-common.S (renamed from libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S)6
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist11
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libpthread.abilist4
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S19
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/sys/ucontext.h (renamed from libc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h)9
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/s390-64/ucontext_i.sym (renamed from libc/sysdeps/unix/sysv/linux/s390/ucontext_i.sym)0
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h2
-rw-r--r--libc/sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c35
-rw-r--r--libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h2
-rw-r--r--libc/sysdeps/unix/sysv/linux/sys/ptrace.h2
-rw-r--r--libc/sysdeps/unix/sysv/linux/tst-fanotify.c1
30 files changed, 492 insertions, 37 deletions
diff --git a/libc/sysdeps/unix/sysv/linux/configure b/libc/sysdeps/unix/sysv/linux/configure
index ab0f03c35..d5ee4ef5d 100644
--- a/libc/sysdeps/unix/sysv/linux/configure
+++ b/libc/sysdeps/unix/sysv/linux/configure
@@ -303,7 +303,8 @@ fi
ac_fn_c_check_header_compile "$LINENO" "linux/fanotify.h" "ac_cv_header_linux_fanotify_h" "/* No default includes. */
"
if test "x$ac_cv_header_linux_fanotify_h" = xyes; then :
- DEFINES="$DEFINES -DHAVE_LINUX_FANOTIFY_H=1"
+ $as_echo "#define HAVE_LINUX_FANOTIFY_H 1" >>confdefs.h
+
fi
diff --git a/libc/sysdeps/unix/sysv/linux/configure.ac b/libc/sysdeps/unix/sysv/linux/configure.ac
index 6d6053f27..90cbf4894 100644
--- a/libc/sysdeps/unix/sysv/linux/configure.ac
+++ b/libc/sysdeps/unix/sysv/linux/configure.ac
@@ -108,7 +108,7 @@ fi
# Until we start requiring 2.6.37+ headers, we need to check for the
# availability of linux/fanotify.h for testing purposes.
AC_CHECK_HEADER(linux/fanotify.h,
- [DEFINES="$DEFINES -DHAVE_LINUX_FANOTIFY_H=1"], ,
+ [AC_DEFINE(HAVE_LINUX_FANOTIFY_H)], ,
[/* No default includes. */])
# The result of the above test for the use of the FDE code is invalid if
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 29a5e08ad..97ea2a4a7 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -35,17 +35,36 @@ __gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
void *
gettimeofday_ifunc (void)
{
+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
+
/* If the vDSO is not available we fall back syscall. */
- return (__vdso_gettimeofday ? VDSO_IFUNC_RET (__vdso_gettimeofday)
- : __gettimeofday_syscall);
+ void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
+ return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
+ : (void*)__gettimeofday_syscall);
}
asm (".type __gettimeofday, %gnu_indirect_function");
/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
let us do it in C because it doesn't know we're defining __gettimeofday
here in this file. */
-asm (".globl __GI___gettimeofday\n"
- "__GI___gettimeofday = __gettimeofday");
+asm (".globl __GI___gettimeofday");
+
+/* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
+ compiler make a local call (symbol@local) for internal GLIBC usage. It
+ means the PLT won't be used and the ifunc resolver will be called directly.
+ For ppc64 a call to a function in another translation unit might use a
+ different toc pointer thus disallowing direct branchess and making internal
+ ifuncs calls safe. */
+#ifdef __powerpc64__
+asm ("__GI___gettimeofday = __gettimeofday");
+#else
+int
+__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
+{
+ return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+}
+asm ("__GI___gettimeofday = __gettimeofday_vsyscall");
+#endif
#else
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h
index d798b5a27..dd81efc28 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/sys/ptrace.h
@@ -158,7 +158,7 @@ enum __ptrace_eventcodes
};
/* Arguments for PTRACE_PEEKSIGINFO. */
-struct ptrace_peeksiginfo_args
+struct __ptrace_peeksiginfo_args
{
__uint64_t off; /* From which siginfo to start. */
__uint32_t flags; /* Flags for peeksiginfo. */
diff --git a/libc/sysdeps/unix/sysv/linux/powerpc/time.c b/libc/sysdeps/unix/sysv/linux/powerpc/time.c
index 089d0b69e..9f54d9724 100644
--- a/libc/sysdeps/unix/sysv/linux/powerpc/time.c
+++ b/libc/sysdeps/unix/sysv/linux/powerpc/time.c
@@ -45,17 +45,36 @@ time_syscall (time_t *t)
void *
time_ifunc (void)
{
+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
+
/* If the vDSO is not available we fall back to the syscall. */
- return (__vdso_time ? VDSO_IFUNC_RET (__vdso_time)
- : time_syscall);
+ void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615);
+ return (vdso_time ? VDSO_IFUNC_RET (vdso_time)
+ : (void*)time_syscall);
}
asm (".type time, %gnu_indirect_function");
/* This is doing "libc_hidden_def (time)" but the compiler won't
* let us do it in C because it doesn't know we're defining time
* here in this file. */
-asm (".globl __GI_time\n"
- "__GI_time = time");
+asm (".globl __GI_time");
+
+/* __GI_time is defined as hidden and for ppc32 it enables the
+ compiler make a local call (symbol@local) for internal GLIBC usage. It
+ means the PLT won't be used and the ifunc resolver will be called directly.
+ For ppc64 a call to a function in another translation unit might use a
+ different toc pointer thus disallowing direct branchess and making internal
+ ifuncs calls safe. */
+#ifdef __powerpc64__
+asm ("__GI_time = time");
+#else
+time_t
+__time_vsyscall (time_t *t)
+{
+ return INLINE_VSYSCALL (time, 1, t);
+}
+asm ("__GI_time = __time_vsyscall");
+#endif
#else
diff --git a/libc/sysdeps/unix/sysv/linux/s390/Makefile b/libc/sysdeps/unix/sysv/linux/s390/Makefile
index 45b192233..f91179d0f 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/Makefile
+++ b/libc/sysdeps/unix/sysv/linux/s390/Makefile
@@ -16,3 +16,9 @@ endif
ifeq ($(subdir),elf)
sysdep_routines += dl-vdso
endif
+
+ifeq ($(subdir),debug)
+ifeq (yes,$(build-shared))
+sysdep_routines += v1-longjmp_chk
+endif
+endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/Versions b/libc/sysdeps/unix/sysv/linux/s390/Versions
index 627ff5352..f71a6bd2c 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/Versions
+++ b/libc/sysdeps/unix/sysv/linux/s390/Versions
@@ -1,4 +1,8 @@
libc {
+ GLIBC_2.19 {
+ __longjmp_chk;
+ getcontext;
+ }
GLIBC_PRIVATE {
__vdso_clock_gettime;
__vdso_clock_getres;
diff --git a/libc/sysdeps/unix/sysv/linux/s390/getcontext.S b/libc/sysdeps/unix/sysv/linux/s390/getcontext.S
new file mode 100644
index 000000000..5edbf95cc
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/getcontext.S
@@ -0,0 +1,38 @@
+/* Extendible version of getcontext 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/>. */
+
+#include <libc-symbols.h>
+#include <shlib-compat.h>
+
+versioned_symbol (libc, __v2getcontext, getcontext, GLIBC_2_19)
+#define __getcontext __v2getcontext
+
+#include "getcontext-common.S"
+
+#undef __getcontext
+
+libc_hidden_ver (__v2getcontext, getcontext)
+
+#if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_19)
+# define __V1_UCONTEXT
+compat_symbol (libc, __v1getcontext, getcontext, GLIBC_2_1)
+# define __getcontext __v1getcontext
+# include "getcontext-common.S"
+# undef __getcontext
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/longjmp_chk.c b/libc/sysdeps/unix/sysv/linux/s390/longjmp_chk.c
new file mode 100644
index 000000000..10f542d61
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/longjmp_chk.c
@@ -0,0 +1,44 @@
+/* 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 debug/longjmp_chk.c extended for symbol
+ versioning. */
+
+#include <shlib-compat.h>
+#include <setjmp.h>
+
+/* This place is the only user of these functions. */
+extern void ____v2__longjmp_chk (__jmp_buf __env, int __val)
+ __attribute__ ((__noreturn__));
+
+#if defined NOT_IN_libc
+
+# define __v2__longjmp ____longjmp_chk
+# define __v2__libc_siglongjmp __longjmp_chk
+
+# include <longjmp.c>
+
+#else
+
+# define __v2__longjmp ____v2__longjmp_chk
+# define __v2__libc_siglongjmp __v2__libc_siglongjmp_chk
+
+# include <longjmp.c>
+
+versioned_symbol (libc, __v2__libc_siglongjmp_chk, __longjmp_chk, GLIBC_2_19);
+
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/s390/rtld-getcontext.S b/libc/sysdeps/unix/sysv/linux/s390/rtld-getcontext.S
new file mode 100644
index 000000000..653f2b656
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/rtld-getcontext.S
@@ -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 "getcontext-common.S"
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c b/libc/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
index e74f33576..a1b7a6a1a 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c
@@ -26,8 +26,8 @@
#include <stdint.h>
#include <signal.h>
#include <sys/syscall.h>
-
-#define __longjmp ____longjmp_chk
+#include <libc-symbols.h>
+#include <shlib-compat.h>
#define CHECK_SP(env, guard) \
do \
@@ -51,4 +51,22 @@
} \
} while (0)
-#include "__longjmp.c"
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+# define __longjmp ____longjmp_chk
+# include "__longjmp-common.c"
+
+#else /* !NOT_IN_libc */
+# define __longjmp ____v2__longjmp_chk
+# include "__longjmp-common.c"
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_11, GLIBC_2_19)
+# undef __longjmp
+# define __V1_JMPBUF
+# define __longjmp ____v1__longjmp_chk
+# include "__longjmp-common.c"
+# undef __longjmp
+
+# endif
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext-common.S
index ce2d99430..499203023 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext.S
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/getcontext-common.S
@@ -19,6 +19,7 @@
#include <sysdep.h>
#include <features.h>
+#include "rtld-global-offsets.h"
#include "ucontext_i.h"
/* __getcontext (const ucontext_t *ucp)
@@ -33,10 +34,10 @@
ENTRY(__getcontext)
lr %r1,%r2
- /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask, sigsetsize). */
la %r2,SIG_BLOCK
slr %r3,%r3
- la %r4,SC_MASK(%r1)
+ la %r4,SC_MASK(%r1)
lhi %r5,_NSIG8
svc SYS_ify(rt_sigprocmask)
@@ -59,6 +60,42 @@ ENTRY(__getcontext)
std %f14,SC_FPRS+112(%r1)
std %f15,SC_FPRS+120(%r1)
+ lhi %r2,0
+#ifndef __V1_UCONTEXT
+ bras %r3,0f
+# ifdef IS_IN_rtld
+ /* Within ld.so we can do slightly better by addressing dl_hwap
+ relative to GOT start. */
+1: .long _GLOBAL_OFFSET_TABLE_ - 1b
+ .long C_SYMBOL_NAME(_rtld_global_ro)@GOTOFF
+0: l %r4,0(%r3)
+ la %r4,0(%r3,%r4)
+ l %r5,4(%r3)
+ /* _dl_hwcap is 64 bit and we need the lower 32. */
+ l %r3,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(%r4,%r5)
+# elif PIC
+1: .long _GLOBAL_OFFSET_TABLE_ - 1b
+ .long C_SYMBOL_NAME(_rtld_global_ro)@GOT
+0: l %r4,0(%r3)
+ la %r4,0(%r3,%r4) /* GOT pointer -> r4 */
+ l %r5,4(%r3) /* GOT offset -> r5 */
+ l %r5,0(%r4,%r5) /* GOT slot -> r5 */
+ l %r3,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(%r5)
+# else
+ .long C_SYMBOL_NAME(_dl_hwcap)
+0: l %r3,0(%r3)
+ l %r3,0(%r3)
+# endif
+ tml %r3,512 /* HWCAP_S390_HIGH_GPRS */
+ jz 2f
+ /* highgprs implies zarch so stmh/oill is ok here. */
+ .machine "z900"
+ .machinemode "zarch_nohighgprs"
+ stmh %r0,%r15,SC_HIGHGPRS(%r1)
+ oill %r2,1 /* UCONTEXT_UC_FLAGS_HIGH_GPRS */
+#endif
+2: st %r2,SC_FLGS(%r1)
+
/* Set __getcontext return value to 0. */
slr %r2,%r2
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist b/libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
index b6256d5c2..03f2e8380 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libc.abilist
@@ -1774,6 +1774,17 @@ GLIBC_2.17
GLIBC_2.18
GLIBC_2.18 A
__cxa_thread_atexit_impl F
+GLIBC_2.19
+ GLIBC_2.19 A
+ __longjmp_chk F
+ __setjmp F
+ __sigsetjmp F
+ _longjmp F
+ _setjmp F
+ getcontext F
+ longjmp F
+ setjmp F
+ siglongjmp F
GLIBC_2.2
GLIBC_2.2 A
_IO_adjust_wcolumn F
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libpthread.abilist b/libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libpthread.abilist
index 865364e13..699de0160 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libpthread.abilist
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/nptl/libpthread.abilist
@@ -178,6 +178,10 @@ GLIBC_2.18
GLIBC_2.18 A
pthread_getattr_default_np F
pthread_setattr_default_np F
+GLIBC_2.19
+ GLIBC_2.19 A
+ longjmp F
+ siglongjmp F
GLIBC_2.2
GLIBC_2.2 A
__open64 F
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
index 3008f8e4a..fbe8b77ca 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/setcontext.S
@@ -33,7 +33,7 @@
ENTRY(__setcontext)
lr %r1,%r2
- /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
+ /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */
la %r2,SIG_BLOCK
la %r3,SC_MASK(%r1)
slr %r4,%r4
@@ -62,8 +62,16 @@ ENTRY(__setcontext)
/* Don't touch %a0, used for thread purposes. */
lam %a1,%a15,SC_ACRS+4(%r1)
+ /* Restore the upper halfs if available. */
+ l %r2,SC_FLGS(%r1)
+ tml %r2,1 /* UCONTEXT_UC_FLAGS_HIGH_GPRS */
+ jz 0f
+ .machine "z900"
+ .machinemode "zarch_nohighgprs"
+ lmh %r0,%r15,SC_HIGHGPRS(%r1)
+
/* Load general purpose registers. */
- lm %r0,%r15,SC_GPRS(%r1)
+0: lm %r0,%r15,SC_GPRS(%r1)
/* Return. */
br %r14
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
index 6c40c994e..41ede4b7b 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/swapcontext.S
@@ -33,6 +33,9 @@
other than the PRESERVED state. */
ENTRY(__swapcontext)
+ /* While not part of the ABI a system call never clobbers r0
+ or r1. So keeping the values here while calling
+ rt_sigprocmask is ok. */
lr %r1,%r2
lr %r0,%r3
@@ -62,19 +65,31 @@ ENTRY(__swapcontext)
std %f14,SC_FPRS+112(%r1)
std %f15,SC_FPRS+120(%r1)
- /* Set __swapcontext return value to 0. */
- slr %r2,%r2
-
/* Store access registers. */
stam %a0,%a15,SC_ACRS(%r1)
+ /* Set __swapcontext return value to 0. */
+ slr %r2,%r2
+
/* Store general purpose registers. */
stm %r0,%r15,SC_GPRS(%r1)
- /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
- la %r2,SIG_BLOCK
+ /* Copy uc_flags into the new ucontext_t. */
lr %r5,%r0
- la %r3,SC_MASK(%r5)
+ l %r2,SC_FLGS(%r5)
+ st %r2,SC_FLGS(%r1)
+
+ /* Save/restore the upper halfs if necessary. */
+ tml %r2,1 /* UCONTEXT_UC_FLAGS_HIGH_GPRS */
+ jz 0f
+ .machine "z900"
+ .machinemode "zarch_nohighgprs"
+ stmh %r0,%r15,SC_HIGHGPRS(%r1)
+ lmh %r0,%r15,SC_HIGHGPRS(%r5)
+
+ /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */
+0: la %r2,SIG_BLOCK
+ la %r3,SC_MASK(%r5)
slr %r4,%r4
lhi %r5,_NSIG8
svc SYS_ify(rt_sigprocmask)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/s390/s390-32/sys/ucontext.h
new file mode 100644
index 000000000..90adc2d1f
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/sys/ucontext.h
@@ -0,0 +1,96 @@
+/* Copyright (C) 2000-2013 Free Software Foundation, Inc.
+ Contributed by Denis Joseph Barrow (djbarrow@de.ibm.com).
+ 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/>. */
+
+#ifndef _SYS_UCONTEXT_H
+#define _SYS_UCONTEXT_H 1
+/* Forward definition to avoid parse errors */
+struct ucontext;
+typedef struct ucontext ucontext_t;
+#include <features.h>
+#include <signal.h>
+
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+/* Type for a program status word. */
+typedef struct
+{
+ unsigned long mask;
+ unsigned long addr;
+} __attribute__ ((__aligned__(8))) __psw_t;
+
+/* Type for a general-purpose register. */
+typedef unsigned long greg_t;
+
+/* And the whole bunch of them. We should have used `struct s390_regs',
+ but to avoid name space pollution and since the tradition says that
+ the register set is an array, we make gregset_t a simple array
+ that has the same size as s390_regs. This is needed for the
+ elf_prstatus structure. */
+#if __WORDSIZE == 64
+# define NGREG 27
+#else
+# define NGREG 36
+#endif
+/* Must match kernels psw_t alignment. */
+typedef greg_t gregset_t[NGREG] __attribute__ ((__aligned__(8)));
+
+typedef union
+ {
+ double d;
+ float f;
+ } fpreg_t;
+
+/* Register set for the floating-point registers. */
+typedef struct
+ {
+ unsigned int fpc;
+ fpreg_t fprs[16];
+ } fpregset_t;
+
+/* Bit is set if the uc_high_gprs field contains the upper halfs of
+ the 64 bit general purpose registers. */
+#define UCONTEXT_UC_FLAGS_HIGH_GPRS (1UL << 0)
+
+/* A new uc_flags constant will be defined when actually making use of
+ the reserved space: UCONTEXT_UCFLAGS_RESERVED (1UL << 1). */
+
+/* Context to describe whole processor state. */
+typedef struct
+ {
+ __psw_t psw;
+ unsigned long gregs[16];
+ unsigned int aregs[16];
+ fpregset_t fpregs;
+ } mcontext_t;
+
+/* Userlevel context. */
+struct ucontext
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ unsigned long uc_high_gprs[16];
+ char __reserved[512];
+ };
+
+
+#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-32/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/s390/s390-32/ucontext_i.sym
new file mode 100644
index 000000000..705c7ab6c
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-32/ucontext_i.sym
@@ -0,0 +1,26 @@
+#include <stddef.h>
+#include <signal.h>
+#include <sys/ucontext.h>
+
+--
+
+SIG_BLOCK
+SIG_UNBLOCK
+SIG_SETMASK
+
+_NSIG8 (_NSIG / 8)
+
+#define ucontext(member) offsetof (ucontext_t, member)
+#define mcontext(member) ucontext (uc_mcontext.member)
+
+SC_FLGS ucontext (uc_flags)
+SC_LINK ucontext (uc_link)
+SC_STCK ucontext (uc_stack.ss_sp)
+SC_STSZ ucontext (uc_stack.ss_size)
+SC_PSW mcontext (psw)
+SC_GPRS mcontext (gregs)
+SC_ACRS mcontext (aregs)
+SC_FPC mcontext (fpregs.fpc)
+SC_FPRS mcontext (fpregs.fprs)
+SC_MASK ucontext (uc_sigmask)
+SC_HIGHGPRS ucontext (uc_high_gprs)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c b/libc/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
index a3b1375a0..bc27b0872 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c
@@ -26,8 +26,8 @@
#include <stdint.h>
#include <signal.h>
#include <sys/syscall.h>
-
-#define __longjmp ____longjmp_chk
+#include <libc-symbols.h>
+#include <shlib-compat.h>
#define CHECK_SP(env, guard) \
do \
@@ -51,4 +51,23 @@
} \
} while (0)
-#include "__longjmp.c"
+
+#if defined NOT_IN_libc
+/* Build a non-versioned object for rtld-*. */
+# define __longjmp ____longjmp_chk
+# include "__longjmp-common.c"
+
+#else /* !NOT_IN_libc */
+# define __longjmp ____v2__longjmp_chk
+# include "__longjmp-common.c"
+# undef __longjmp
+
+# if defined SHARED && SHLIB_COMPAT (libc, GLIBC_2_11, GLIBC_2_19)
+# undef __longjmp
+# define __V1_JMPBUF
+# define __longjmp ____v1__longjmp_chk
+# include "__longjmp-common.c"
+# undef __longjmp
+
+# endif
+#endif /* !NOT_IN_libc */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext-common.S
index db271c5dc..3e61e3070 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/getcontext-common.S
@@ -33,7 +33,7 @@
ENTRY(__getcontext)
lgr %r1,%r2
- /* sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask). */
+ /* rt_sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask, sigsetsize). */
la %r2,SIG_BLOCK
slgr %r3,%r3
la %r4,SC_MASK(%r1)
@@ -62,6 +62,10 @@ ENTRY(__getcontext)
/* Set __getcontext return value to 0. */
slgr %r2,%r2
+ /* Store the version number into the uc_flags field. So far
+ we do not make use of the reserved bytes so we store a zero. */
+ stg %r2,SC_FLGS(%r1)
+
/* Store access registers. */
stam %a0,%a15,SC_ACRS(%r1)
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist b/libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
index 265f66d90..4576fc8d1 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libc.abilist
@@ -95,6 +95,17 @@ GLIBC_2.17
GLIBC_2.18
GLIBC_2.18 A
__cxa_thread_atexit_impl F
+GLIBC_2.19
+ GLIBC_2.19 A
+ __longjmp_chk F
+ __setjmp F
+ __sigsetjmp F
+ _longjmp F
+ _setjmp F
+ getcontext F
+ longjmp F
+ setjmp F
+ siglongjmp F
GLIBC_2.2
GLIBC_2.2 A
_Exit F
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libpthread.abilist b/libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libpthread.abilist
index 6613c09b0..51a8a7ff6 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libpthread.abilist
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/nptl/libpthread.abilist
@@ -12,6 +12,10 @@ GLIBC_2.18
GLIBC_2.18 A
pthread_getattr_default_np F
pthread_setattr_default_np F
+GLIBC_2.19
+ GLIBC_2.19 A
+ longjmp F
+ siglongjmp F
GLIBC_2.2
GLIBC_2.2 A
_IO_flockfile F
diff --git a/libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S b/libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
index ec9289896..ac74b6bc0 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/swapcontext.S
@@ -33,6 +33,9 @@
other than the PRESERVED state. */
ENTRY(__swapcontext)
+ /* While not part of the ABI a system call never clobbers r0
+ or r1. So keeping the values here while calling
+ rt_sigprocmask is ok. */
lgr %r1,%r2
lgr %r0,%r3
@@ -62,21 +65,25 @@ ENTRY(__swapcontext)
std %f14,SC_FPRS+112(%r1)
std %f15,SC_FPRS+120(%r1)
- /* Set __swapcontext return value to 0. */
- slgr %r2,%r2
-
/* Store access registers. */
stam %a0,%a15,SC_ACRS(%r1)
+ /* Set __swapcontext return value to 0. */
+ slgr %r2,%r2
+
/* Store general purpose registers. */
stmg %r0,%r15,SC_GPRS(%r1)
- /* sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL). */
- la %r2,SIG_BLOCK
+ /* Copy uc_flags into the new ucontext_t. */
lgr %r5,%r0
+ lg %r2,SC_FLGS(%r5)
+ stg %r2,SC_FLGS(%r1)
+
+ /* rt_sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL, sigsetsize). */
+ la %r2,SIG_BLOCK
la %r3,SC_MASK(%r5)
- lghi %r5,_NSIG8
slgr %r4,%r4
+ lghi %r5,_NSIG8
svc SYS_ify(rt_sigprocmask)
/* Load fpu context. */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sys/ucontext.h
index d528cb189..b563e98f0 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/sys/ucontext.h
@@ -64,6 +64,14 @@ typedef struct
fpreg_t fprs[16];
} fpregset_t;
+/* Bit 0 is reserved for the uc_high_gprs field only available in the
+ 32 bit version of ucontext_t. This bit will never be set for 64
+ bit. */
+#define UCONTEXT_UC_FLAGS_HIGH_GPRS (1UL << 0)
+
+/* A new uc_flags constant will be defined when actually making use of
+ the reserved space: UCONTEXT_UCFLAGS_RESERVED (1UL << 1). */
+
/* Context to describe whole processor state. */
typedef struct
{
@@ -81,6 +89,7 @@ struct ucontext
stack_t uc_stack;
mcontext_t uc_mcontext;
__sigset_t uc_sigmask;
+ char reserved[512];
};
diff --git a/libc/sysdeps/unix/sysv/linux/s390/ucontext_i.sym b/libc/sysdeps/unix/sysv/linux/s390/s390-64/ucontext_i.sym
index 6cc9f1962..6cc9f1962 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/ucontext_i.sym
+++ b/libc/sysdeps/unix/sysv/linux/s390/s390-64/ucontext_i.sym
diff --git a/libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h
index d86188e5f..741dce6f9 100644
--- a/libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h
+++ b/libc/sysdeps/unix/sysv/linux/s390/sys/ptrace.h
@@ -197,7 +197,7 @@ enum __ptrace_eventcodes
};
/* Arguments for PTRACE_PEEKSIGINFO. */
-struct ptrace_peeksiginfo_args
+struct __ptrace_peeksiginfo_args
{
__uint64_t off; /* From which siginfo to start. */
__uint32_t flags; /* Flags for peeksiginfo. */
diff --git a/libc/sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c b/libc/sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c
new file mode 100644
index 000000000..bd80acfe6
--- /dev/null
+++ b/libc/sysdeps/unix/sysv/linux/s390/v1-longjmp_chk.c
@@ -0,0 +1,35 @@
+/* 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 went into a separate source file since we would otherwise be
+ needed to include two different versions of setjmp.h into the same
+ file. */
+
+#include <shlib-compat.h>
+
+#if !defined NOT_IN_libc && defined SHARED
+# if SHLIB_COMPAT (libc, GLIBC_2_11, GLIBC_2_19)
+
+# define __v1__longjmp ____v1__longjmp_chk
+# define __v1__libc_siglongjmp __v1__libc_siglongjmp_chk
+
+# include <v1-longjmp.c>
+
+compat_symbol (libc, __v1__libc_siglongjmp_chk, __longjmp_chk, GLIBC_2_11);
+
+# endif
+#endif
diff --git a/libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h
index 2395c310a..0f6c2ccae 100644
--- a/libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h
+++ b/libc/sysdeps/unix/sysv/linux/sparc/sys/ptrace.h
@@ -240,7 +240,7 @@ enum __ptrace_eventcodes
};
/* Arguments for PTRACE_PEEKSIGINFO. */
-struct ptrace_peeksiginfo_args
+struct __ptrace_peeksiginfo_args
{
__uint64_t off; /* From which siginfo to start. */
__uint32_t flags; /* Flags for peeksiginfo. */
diff --git a/libc/sysdeps/unix/sysv/linux/sys/ptrace.h b/libc/sysdeps/unix/sysv/linux/sys/ptrace.h
index ddcefba63..e800562e8 100644
--- a/libc/sysdeps/unix/sysv/linux/sys/ptrace.h
+++ b/libc/sysdeps/unix/sysv/linux/sys/ptrace.h
@@ -188,7 +188,7 @@ enum __ptrace_eventcodes
};
/* Arguments for PTRACE_PEEKSIGINFO. */
-struct ptrace_peeksiginfo_args
+struct __ptrace_peeksiginfo_args
{
__uint64_t off; /* From which siginfo to start. */
__uint32_t flags; /* Flags for peeksiginfo. */
diff --git a/libc/sysdeps/unix/sysv/linux/tst-fanotify.c b/libc/sysdeps/unix/sysv/linux/tst-fanotify.c
index 43d3bb269..fb3c77eaa 100644
--- a/libc/sysdeps/unix/sysv/linux/tst-fanotify.c
+++ b/libc/sysdeps/unix/sysv/linux/tst-fanotify.c
@@ -16,6 +16,7 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <config.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>