From 365c597ff1d757dee12fd30a3610a9e8bb61e8f3 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Sun, 25 Feb 2018 09:48:39 -0800
Subject: [PATCH] x86: Add __sigsetjmp_cancel and __setjmp_cancel
Functions, like LIBC_START_MAIN, START_THREAD_DEFN as well as these
with thread cancellation, call setjmp, but never return to their
callers after longjmp returns. This patch adds <bits/setjmp-cancel.h>
and <setjmp-cancelP.h> to provide a version of setjmp family functions,
__setjmp_cancel and __sigsetjmp_cancel, which are used to implement
thread cancellation. The default __setjmp_cancel and __sigsetjmp_cancel
are defined as setjmp and __sigsetjmp, respectively, which are the same
as before.
On x86, __sigsetjmp_cancel, which is a public function used by macros
in <pthread.h>, and __setjmp_cancel, which is a private interface for
cancellation implementation in libpthread, are added to avoid saving
and restoring shadow stack register. A new version of __sigsetjmp is
added to save and restore shadow stack register. The compatible version
of __sigsetjmp, which doesn't save and restore shadow stack register,
is provided for shared libraries built with glibc 2.27 or older.
__libc_longjmp, which is a private interface for cancellation
implementation in libpthread, is changed to call __longjmp_cancel
instead of __longjmp.
NB: Shared libraries built with glibc 2.27 or older are compatible with
glibc 2.28. Relocatable objects compiled against glibc 2.27 or older
are incompatible with glibc 2.28 since they reference the older version
of __sigsetjmp.
Tested with build-many-glibcs.py.
* bits/setjmp-cancel.h: New file.
* sysdeps/generic/setjmp-cancelP.h: Likewise.
* sysdeps/x86/__longjmp_cancel.S: Likewise.
* sysdeps/x86/bits/setjmp-cancel.h: Likewise.
* sysdeps/x86/bsd-_setjmp_cancel.S: Likewise.
* sysdeps/x86/longjmp.c: Likewise.
* sysdeps/x86/setjmp-cancelP.h: Likewise.
* sysdeps/x86/setjmp_cancel.S: Likewise.
* sysdeps/x86_64/setjmp_cancel.S: Likewise.
* csu/libc-start.c (LIBC_START_MAIN): Replace setjmp with
__setjmp_cancel.
* nptl/pthread_create.c (START_THREAD_DEFN): Likewise.
* include/setjmp.h: Include <setjmp-cancelP.h> and
<bits/setjmp-cancel.h>.
* nptl/Makefile (headers): Add bits/setjmp-cancel.h.
* setjmp/longjmp.c (__libc_longjmp): Don't define alias if
defined.
* sysdeps/i386/bsd-_setjmp.S (_setjmp): Don't add hidden_def.
* sysdeps/x86_64/bsd-_setjmp.S (_setjmp): Likewise.
* sysdeps/i386/setjmp.S (__sigsetjmp): Don't add hidden_def and
redefined to __redirect___sigsetjmp in libc.so if __sigsetjmp
is undefined.
(__GI___sigsetjmp): New. Defined if __redirect___sigsetjmp is
defined.
(__sigsetjmp): Add to GLIBC_2_28 if __redirect___sigsetjmp is
defined.
* sysdeps/x86_64/setjmp.S: Likewise.
* sysdeps/nptl/pthread.h (pthread_cleanup_push): Replace
__sigsetjmp with __sigsetjmp_cancel.
(pthread_cleanup_push_defer_np): Likewise.
(__jmp_buf_tag): Removed.
(__sigsetjmp): Likewise.
Include <bits/setjmp-cancel.h>.
* sysdeps/unix/sysv/linux/i386/libc.abilist: Regenerated.
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.
* sysdeps/x86/Makefile (sysdep_routines): Add
bsd-_setjmp_cancel, __longjmp_cancel and setjmp_cancel.
* sysdeps/x86/Versions (__sigsetjmp): Add to GLIBC_2.28
in libc.
(__sigsetjmp_cancel): Likewise.
(__setjmp_cancel): Add to GLIBC_PRIVATE in libc.
* sysdeps/x86_64/bsd-_setjmp.S (SIGSETJMP): New.
(_setjmp): Jmp to SIGSETJMP.
---
bits/setjmp-cancel.h | 33 +++++++++++++++++++
csu/libc-start.c | 2 +-
include/setjmp.h | 3 ++
nptl/Makefile | 2 +-
nptl/pthread_create.c | 2 +-
setjmp/longjmp.c | 2 ++
sysdeps/generic/setjmp-cancelP.h | 19 +++++++++++
sysdeps/i386/bsd-_setjmp.S | 2 ++
sysdeps/i386/setjmp.S | 16 +++++++++-
sysdeps/nptl/pthread.h | 15 +++++----
sysdeps/unix/sysv/linux/i386/libc.abilist | 3 ++
sysdeps/unix/sysv/linux/x86_64/64/libc.abilist | 3 ++
sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist | 3 ++
sysdeps/x86/Makefile | 4 +++
sysdeps/x86/Versions | 12 +++++++
sysdeps/x86/__longjmp_cancel.S | 20 ++++++++++++
sysdeps/x86/bits/setjmp-cancel.h | 31 ++++++++++++++++++
sysdeps/x86/bsd-_setjmp_cancel.S | 22 +++++++++++++
sysdeps/x86/longjmp.c | 42 +++++++++++++++++++++++++
sysdeps/x86/setjmp-cancelP.h | 24 ++++++++++++++
sysdeps/x86/setjmp_cancel.S | 26 +++++++++++++++
sysdeps/x86_64/bsd-_setjmp.S | 25 ++++++++++++---
sysdeps/x86_64/setjmp.S | 16 +++++++++-
sysdeps/x86_64/setjmp_cancel.S | 21 +++++++++++++
24 files changed, 330 insertions(+), 18 deletions(-)
create mode 100644 bits/setjmp-cancel.h
create mode 100644 sysdeps/generic/setjmp-cancelP.h
create mode 100644 sysdeps/x86/__longjmp_cancel.S
create mode 100644 sysdeps/x86/bits/setjmp-cancel.h
create mode 100644 sysdeps/x86/bsd-_setjmp_cancel.S
create mode 100644 sysdeps/x86/longjmp.c
create mode 100644 sysdeps/x86/setjmp-cancelP.h
create mode 100644 sysdeps/x86/setjmp_cancel.S
create mode 100644 sysdeps/x86_64/setjmp_cancel.S
new file mode 100644
@@ -0,0 +1,33 @@
+/* __sigsetjmp_cancel for thread cancellation. Generic version.
+ Copyright (C) 2018 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/>. */
+
+#ifndef _BITS_SETJMP_CANCEL_H
+#define _BITS_SETJMP_CANCEL_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp-cancel.h> directly; use <setjmp.h> instead."
+#endif
+
+#define __sigsetjmp_cancel __sigsetjmp
+
+struct __jmp_buf_tag;
+/* Function used in the macros. */
+extern int __sigsetjmp (struct __jmp_buf_tag *__env,
+ int __savemask) __THROWNL;
+
+#endif /* bits/setjmp-cancel.h */
@@ -292,7 +292,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
struct pthread_unwind_buf unwind_buf;
int not_first_call;
- not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
+ not_first_call = __setjmp_cancel ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
if (__glibc_likely (! not_first_call))
{
struct pthread *self = THREAD_SELF;
@@ -31,6 +31,9 @@ libc_hidden_proto (__sigsetjmp)
extern __typeof (__sigsetjmp) __sigsetjmp attribute_hidden;
# endif
+# include <setjmp-cancelP.h>
+# include <bits/setjmp-cancel.h>
+
/* Check jmp_buf sizes, alignments and offsets. */
# include <stddef.h>
# include <jmp_buf-macros.h>
@@ -22,7 +22,7 @@ subdir := nptl
include ../Makeconfig
-headers := pthread.h semaphore.h bits/semaphore.h
+headers := pthread.h semaphore.h bits/semaphore.h bits/setjmp-cancel.h
extra-libs := libpthread
extra-libs-others := $(extra-libs)
@@ -432,7 +432,7 @@ START_THREAD_DEFN
unwind_buf.priv.data.cleanup = NULL;
int not_first_call;
- not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
+ not_first_call = __setjmp_cancel ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
if (__glibc_likely (! not_first_call))
{
/* Store the new cleanup handler info. */
@@ -40,9 +40,11 @@ __libc_siglongjmp (sigjmp_buf env, int val)
}
#ifndef __libc_siglongjmp
+# ifndef __libc_longjmp
/* __libc_longjmp is a private interface for cancellation implementation
in libpthread. */
strong_alias (__libc_siglongjmp, __libc_longjmp)
+# endif
weak_alias (__libc_siglongjmp, _longjmp)
weak_alias (__libc_siglongjmp, longjmp)
weak_alias (__libc_siglongjmp, siglongjmp)
new file mode 100644
@@ -0,0 +1,19 @@
+/* Internal header file for <bits/setjmp-cancel.h>. Generic version.
+ Copyright (C) 2017-2018 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/>. */
+
+#define __setjmp_cancel setjmp
@@ -53,4 +53,6 @@ ENTRY (_setjmp)
movl %eax, JB_SIZE(%edx) /* No signal mask set. */
ret
END (_setjmp)
+#ifndef _setjmp
libc_hidden_def (_setjmp)
+#endif
@@ -25,6 +25,11 @@
#define JMPBUF PARMS
#define SIGMSK JMPBUF+4
+#if !defined __sigsetjmp && defined SHARED && !IS_IN (rtld)
+# define __sigsetjmp __redirect___sigsetjmp
+# define __redirect___sigsetjmp __redirect___sigsetjmp
+#endif
+
ENTRY (__sigsetjmp)
movl JMPBUF(%esp), %eax
@@ -55,4 +60,13 @@ ENTRY (__sigsetjmp)
jmp __sigjmp_save
#endif
END (__sigsetjmp)
-hidden_def (__sigsetjmp)
+#ifdef __redirect___sigsetjmp
+# undef __sigsetjmp
+
+ .globl __GI___sigsetjmp
+ .hidden __GI___sigsetjmp
+ __GI___sigsetjmp = __redirect___sigsetjmp
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __redirect___sigsetjmp, __sigsetjmp, GLIBC_2_28);
+#endif
@@ -667,8 +667,9 @@ __pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame)
__pthread_unwind_buf_t __cancel_buf; \
void (*__cancel_routine) (void *) = (routine); \
void *__cancel_arg = (arg); \
- int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
- __cancel_buf.__cancel_jmp_buf, 0); \
+ int __not_first_call \
+ = __sigsetjmp_cancel ((struct __jmp_buf_tag *) (void *) \
+ __cancel_buf.__cancel_jmp_buf, 0); \
if (__glibc_unlikely (__not_first_call)) \
{ \
__cancel_routine (__cancel_arg); \
@@ -702,8 +703,9 @@ extern void __pthread_unregister_cancel (__pthread_unwind_buf_t *__buf)
__pthread_unwind_buf_t __cancel_buf; \
void (*__cancel_routine) (void *) = (routine); \
void *__cancel_arg = (arg); \
- int __not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *) \
- __cancel_buf.__cancel_jmp_buf, 0); \
+ int __not_first_call \
+ = __sigsetjmp_cancel ((struct __jmp_buf_tag *) (void *) \
+ __cancel_buf.__cancel_jmp_buf, 0); \
if (__glibc_unlikely (__not_first_call)) \
{ \
__cancel_routine (__cancel_arg); \
@@ -739,10 +741,7 @@ extern void __pthread_unwind_next (__pthread_unwind_buf_t *__buf)
;
#endif
-/* Function used in the macros. */
-struct __jmp_buf_tag;
-extern int __sigsetjmp (struct __jmp_buf_tag *__env, int __savemask) __THROWNL;
-
+#include <bits/setjmp-cancel.h>
/* Mutex handling. */
@@ -2064,6 +2064,9 @@ GLIBC_2.27 wcstof64 F
GLIBC_2.27 wcstof64_l F
GLIBC_2.27 wcstof64x F
GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 GLIBC_2.28 A
+GLIBC_2.28 __sigsetjmp F
+GLIBC_2.28 __sigsetjmp_cancel F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
@@ -1905,6 +1905,9 @@ GLIBC_2.27 wcstof64 F
GLIBC_2.27 wcstof64_l F
GLIBC_2.27 wcstof64x F
GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 GLIBC_2.28 A
+GLIBC_2.28 __sigsetjmp F
+GLIBC_2.28 __sigsetjmp_cancel F
GLIBC_2.3 GLIBC_2.3 A
GLIBC_2.3 __ctype_b_loc F
GLIBC_2.3 __ctype_tolower_loc F
@@ -2148,3 +2148,6 @@ GLIBC_2.27 wcstof64 F
GLIBC_2.27 wcstof64_l F
GLIBC_2.27 wcstof64x F
GLIBC_2.27 wcstof64x_l F
+GLIBC_2.28 GLIBC_2.28 A
+GLIBC_2.28 __sigsetjmp F
+GLIBC_2.28 __sigsetjmp_cancel F
@@ -8,3 +8,7 @@ sysdep-dl-routines += dl-get-cpu-features
tests += tst-get-cpu-features
tests-static += tst-get-cpu-features-static
endif
+
+ifeq ($(subdir),setjmp)
+sysdep_routines += bsd-_setjmp_cancel __longjmp_cancel setjmp_cancel
+endif
@@ -3,3 +3,15 @@ ld {
__get_cpu_features;
}
}
+libc {
+ GLIBC_2.28 {
+ __sigsetjmp;
+
+ # used to implement thread cancellation.
+ __sigsetjmp_cancel;
+ }
+ GLIBC_PRIVATE {
+ # used to implement thread cancellation.
+ __setjmp_cancel;
+ }
+}
new file mode 100644
@@ -0,0 +1,20 @@
+/* __longjmp_cancel for x86.
+ Copyright (C) 2018 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/>. */
+
+#define __longjmp __longjmp_cancel
+#include <__longjmp.S>
new file mode 100644
@@ -0,0 +1,31 @@
+/* __sigsetjmp_cancel for thread cancellation. x86 version.
+ Copyright (C) 2018 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/>. */
+
+#ifndef _BITS_SETJMP_CANCEL_H
+#define _BITS_SETJMP_CANCEL_H 1
+
+#if !defined _SETJMP_H && !defined _PTHREAD_H
+# error "Never include <bits/setjmp-cancel.h> directly; use <setjmp.h> instead."
+#endif
+
+/* Function used in the macros. */
+struct __jmp_buf_tag;
+extern int __sigsetjmp_cancel (struct __jmp_buf_tag *__env, int __savemask)
+ __THROWNL __attribute__((__returns_twice__));
+
+#endif /* bits/setjmp-cancel.h */
new file mode 100644
@@ -0,0 +1,22 @@
+/* __setjmp_cancel for x86.
+ Copyright (C) 2018 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/>. */
+
+#define _setjmp __setjmp_cancel
+#include <bsd-_setjmp.S>
+
+libc_hidden_def (__setjmp_cancel)
new file mode 100644
@@ -0,0 +1,42 @@
+/* __libc_siglongjmp for x86.
+ Copyright (C) 2018 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/>. */
+
+#define __libc_longjmp __redirect___libc_longjmp
+#include <setjmp/longjmp.c>
+#undef __libc_longjmp
+
+/* Since __libc_longjmp is a private interface for cancellation
+ implementation in libpthread, there is no need to restore shadow
+ stack register. */
+
+void
+__libc_longjmp (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,
+ (sigset_t *) &env[0].__saved_mask,
+ (sigset_t *) NULL);
+
+ /* Call the machine-dependent function to restore machine state
+ without shadow stack. */
+ __longjmp_cancel (env[0].__jmpbuf, val ?: 1);
+}
new file mode 100644
@@ -0,0 +1,24 @@
+/* Internal header file for <bits/setjmp-cancel.h>. x86 version.
+ Copyright (C) 2017-2018 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/>. */
+
+extern int __setjmp_cancel (struct __jmp_buf_tag __env[1])
+ __attribute__((__returns_twice__));
+libc_hidden_proto (__setjmp_cancel, __returns_twice__)
+
+extern void __longjmp_cancel (__jmp_buf __env, int __val)
+ __attribute__ ((__noreturn__)) attribute_hidden;
new file mode 100644
@@ -0,0 +1,26 @@
+/* __sigsetjmp_cancel for x86.
+ Copyright (C) 2018 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/>. */
+
+#define __sigsetjmp __sigsetjmp_cancel
+#include <setjmp.S>
+#undef __sigsetjmp
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_28)
+compat_symbol (libc, __sigsetjmp_cancel, __sigsetjmp, GLIBC_2_0);
+#endif
@@ -25,13 +25,28 @@
#define _SETJMP_H
#include <bits/setjmp.h>
+/* If _setjmp is defined for __setjmp_cancel, call __sigsetjmp_cancel
+ instead of __sigsetjmp.
+ */
+#ifdef _setjmp
+# ifdef PIC
+# define SIGSETJMP HIDDEN_JUMPTARGET (__sigsetjmp_cancel)
+# else
+# define SIGSETJMP __sigsetjmp_cancel
+# endif
+#else
+# ifdef PIC
+# define SIGSETJMP HIDDEN_JUMPTARGET (__sigsetjmp)
+# else
+# define SIGSETJMP __sigsetjmp
+# endif
+#endif
+
ENTRY (_setjmp)
/* Set up arguments, we only need to set the second arg. */
xorl %esi, %esi
-#ifdef PIC
- jmp HIDDEN_JUMPTARGET (__sigsetjmp)
-#else
- jmp __sigsetjmp
-#endif
+ jmp SIGSETJMP
END (_setjmp)
+#ifndef _setjmp
libc_hidden_def (_setjmp)
+#endif
@@ -21,6 +21,11 @@
#include <asm-syntax.h>
#include <stap-probe.h>
+#if !defined __sigsetjmp && defined SHARED && !IS_IN (rtld)
+# define __sigsetjmp __redirect___sigsetjmp
+# define __redirect___sigsetjmp __redirect___sigsetjmp
+#endif
+
ENTRY (__sigsetjmp)
/* Save registers. */
movq %rbx, (JB_RBX*8)(%rdi)
@@ -63,4 +68,13 @@ ENTRY (__sigsetjmp)
jmp __sigjmp_save
#endif
END (__sigsetjmp)
-hidden_def (__sigsetjmp)
+#ifdef __redirect___sigsetjmp
+# undef __sigsetjmp
+
+ .globl __GI___sigsetjmp
+ .hidden __GI___sigsetjmp
+ __GI___sigsetjmp = __redirect___sigsetjmp
+
+# include <shlib-compat.h>
+versioned_symbol (libc, __redirect___sigsetjmp, __sigsetjmp, GLIBC_2_28);
+#endif
new file mode 100644
@@ -0,0 +1,21 @@
+/* __sigsetjmp_cancel for x86-64.
+ Copyright (C) 2018 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 <sysdeps/x86/setjmp_cancel.S>
+
+libc_hidden_def (__sigsetjmp_cancel)
--
2.14.3