This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch hjl/pr22743/master created. glibc-2.26.9000-1162-g4b7fc47
- From: hjl at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 25 Jan 2018 05:29:55 -0000
- Subject: GNU C Library master sources branch hjl/pr22743/master created. glibc-2.26.9000-1162-g4b7fc47
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, hjl/pr22743/master has been created
at 4b7fc470a6740808b41502d7431f91805e272d26 (commit)
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=4b7fc470a6740808b41502d7431f91805e272d26
commit 4b7fc470a6740808b41502d7431f91805e272d26
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Wed Jan 24 15:27:49 2018 -0800
x86: Add pthread_create@GLIBC_2.27
Applications compiled against header files older than glibc 2.27 must
use the compatible struct __cancel_jmp_buf_tag. Such applications are
identified by pthread_create older than GLIBC_2.27.
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 605222f..a41efeb 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -298,8 +298,10 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
struct pthread *self = THREAD_SELF;
/* Store old info. */
- unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
- unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup);
+ unwind_buf_priv (self, &unwind_buf)->data.prev
+ = THREAD_GETMEM (self, cleanup_jmp_buf);
+ unwind_buf_priv (self, &unwind_buf)->data.cleanup
+ = THREAD_GETMEM (self, cleanup);
/* Store the new cleanup handler info. */
THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf);
diff --git a/nptl/cleanup.c b/nptl/cleanup.c
index d21b86e..7fef607 100644
--- a/nptl/cleanup.c
+++ b/nptl/cleanup.c
@@ -28,8 +28,10 @@ __pthread_register_cancel (__pthread_unwind_buf_t *buf)
struct pthread *self = THREAD_SELF;
/* Store old info. */
- ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
- ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup);
+ unwind_buf_priv (self, ibuf)->data.prev
+ = THREAD_GETMEM (self, cleanup_jmp_buf);
+ unwind_buf_priv (self, ibuf)->data.cleanup
+ = THREAD_GETMEM (self, cleanup);
/* Store the new cleanup handler info. */
THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf);
@@ -42,7 +44,9 @@ __cleanup_fct_attribute
__pthread_unregister_cancel (__pthread_unwind_buf_t *buf)
{
struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
+ struct pthread *self = THREAD_SELF;
- THREAD_SETMEM (THREAD_SELF, cleanup_jmp_buf, ibuf->priv.data.prev);
+ THREAD_SETMEM (self, cleanup_jmp_buf,
+ unwind_buf_priv (self, ibuf)->data.prev);
}
hidden_def (__pthread_unregister_cancel)
diff --git a/nptl/cleanup_defer.c b/nptl/cleanup_defer.c
index 5701ce4..64d7eb7 100644
--- a/nptl/cleanup_defer.c
+++ b/nptl/cleanup_defer.c
@@ -28,8 +28,10 @@ __pthread_register_cancel_defer (__pthread_unwind_buf_t *buf)
struct pthread *self = THREAD_SELF;
/* Store old info. */
- ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
- ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup);
+ unwind_buf_priv (self, ibuf)->data.prev
+ = THREAD_GETMEM (self, cleanup_jmp_buf);
+ unwind_buf_priv (self, ibuf)->data.cleanup
+ = THREAD_GETMEM (self, cleanup);
int cancelhandling = THREAD_GETMEM (self, cancelhandling);
@@ -49,9 +51,9 @@ __pthread_register_cancel_defer (__pthread_unwind_buf_t *buf)
cancelhandling = curval;
}
- ibuf->priv.data.canceltype = (cancelhandling & CANCELTYPE_BITMASK
- ? PTHREAD_CANCEL_ASYNCHRONOUS
- : PTHREAD_CANCEL_DEFERRED);
+ unwind_buf_priv (self, ibuf)->data.canceltype
+ = (cancelhandling & CANCELTYPE_BITMASK
+ ? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);
/* Store the new cleanup handler info. */
THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf);
@@ -65,10 +67,11 @@ __pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf)
struct pthread *self = THREAD_SELF;
struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
- THREAD_SETMEM (self, cleanup_jmp_buf, ibuf->priv.data.prev);
+ THREAD_SETMEM (self, cleanup_jmp_buf,
+ unwind_buf_priv (self, ibuf)->data.prev);
int cancelhandling;
- if (ibuf->priv.data.canceltype != PTHREAD_CANCEL_DEFERRED
+ if (unwind_buf_priv (self, ibuf)->data.canceltype != PTHREAD_CANCEL_DEFERRED
&& ((cancelhandling = THREAD_GETMEM (self, cancelhandling))
& CANCELTYPE_BITMASK) == 0)
{
diff --git a/nptl/descr.h b/nptl/descr.h
index 1cc6b09..a95eba8 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -56,10 +56,29 @@
+union pthread_unwind_buf_data
+{
+ /* This is the placeholder of the public version. */
+ void *pad[4];
-/* Internal version of the buffer to store cancellation handler
+ struct
+ {
+ /* Pointer to the previous cleanup buffer. */
+ struct pthread_unwind_buf *prev;
+
+ /* Backward compatibility: state of the old-style cleanup
+ handler at the time of the previous new-style cleanup handler
+ installment. */
+ struct _pthread_cleanup_buffer *cleanup;
+
+ /* Cancellation type before the push call. */
+ int canceltype;
+ } data;
+};
+
+/* Internal updated version of the buffer to store cancellation handler
information. */
-struct pthread_unwind_buf
+struct updated_pthread_unwind_buf
{
struct
{
@@ -70,27 +89,47 @@ struct pthread_unwind_buf
#endif
} cancel_jmp_buf[1];
- union
+ union pthread_unwind_buf_data priv;
+};
+
+/* Internal compatible version of the buffer to store cancellation
+ handler information. */
+struct compat_pthread_unwind_buf
+{
+ struct
{
- /* This is the placeholder of the public version. */
- void *pad[4];
+ __jmp_buf jmp_buf;
+ int mask_was_saved;
+ } cancel_jmp_buf[1];
+
+ union pthread_unwind_buf_data priv;
+};
+/* Internal version of the buffer to store cancellation handler
+ information. */
+struct pthread_unwind_buf
+{
+ union
+ {
struct
{
- /* Pointer to the previous cleanup buffer. */
- struct pthread_unwind_buf *prev;
-
- /* Backward compatibility: state of the old-style cleanup
- handler at the time of the previous new-style cleanup handler
- installment. */
- struct _pthread_cleanup_buffer *cleanup;
-
- /* Cancellation type before the push call. */
- int canceltype;
- } data;
- } priv;
+ __jmp_buf jmp_buf;
+ int mask_was_saved;
+ } cancel_jmp_buf[1];
+ struct updated_pthread_unwind_buf updated;
+ struct compat_pthread_unwind_buf compat;
+ };
};
+/* Macro to access the priv field. By default, the compatible version
+ is used. If a target defines NEED_SAVED_MASK_IN_CANCEL_JMP_BUF, it
+ must provide its own version of unwind_buf_priv. */
+#ifndef unwind_buf_priv
+# ifdef NEED_SAVED_MASK_IN_CANCEL_JMP_BUF
+# error "unwind_buf_priv is undefined!"
+# endif
+# define unwind_buf_priv(self,p) (&((p)->compat.priv))
+#endif
/* Opcodes and data types for communication with the signal handler to
change user/group IDs. */
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index caaf07c..4df08b3 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -428,8 +428,8 @@ START_THREAD_DEFN
struct pthread_unwind_buf unwind_buf;
/* No previous handlers. */
- unwind_buf.priv.data.prev = NULL;
- unwind_buf.priv.data.cleanup = NULL;
+ unwind_buf_priv (pd, &unwind_buf)->data.prev = NULL;
+ unwind_buf_priv (pd, &unwind_buf)->data.cleanup = NULL;
int not_first_call;
not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
@@ -853,7 +853,9 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr,
return retval;
}
+#ifndef NEED_SAVED_MASK_IN_CANCEL_JMP_BUF
versioned_symbol (libpthread, __pthread_create_2_1, pthread_create, GLIBC_2_1);
+#endif
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
diff --git a/nptl/unwind.c b/nptl/unwind.c
index b37a063..076e0b4 100644
--- a/nptl/unwind.c
+++ b/nptl/unwind.c
@@ -66,7 +66,8 @@ unwind_stop (int version, _Unwind_Action actions,
/* Handle the compatibility stuff. Execute all handlers
registered with the old method which would be unwound by this
step. */
- struct _pthread_cleanup_buffer *oldp = buf->priv.data.cleanup;
+ struct _pthread_cleanup_buffer *oldp
+ = unwind_buf_priv (self, buf)->data.cleanup;
void *cfa = (void *) (_Unwind_Ptr) _Unwind_GetCFA (context);
if (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp, adj)))
@@ -133,6 +134,7 @@ __pthread_unwind_next (__pthread_unwind_buf_t *buf)
{
struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
- __pthread_unwind ((__pthread_unwind_buf_t *) ibuf->priv.data.prev);
+ __pthread_unwind ((__pthread_unwind_buf_t *)
+ unwind_buf_priv (THREAD_SELF, ibuf)->data.prev);
}
hidden_def (__pthread_unwind_next)
diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h
index 30643d4..f140084 100644
--- a/sysdeps/i386/nptl/tls.h
+++ b/sysdeps/i386/nptl/tls.h
@@ -52,6 +52,7 @@ typedef struct
void *__private_ss;
/* Bit 0: IBT.
Bit 1: SHSTK.
+ Bit 2: Compatible struct __cancel_jmp_buf_tag before glibc 2.27.
*/
unsigned int feature_1;
} tcbhead_t;
diff --git a/sysdeps/unix/sysv/linux/i386/libpthread.abilist b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
index 8f9c325..84f7246 100644
--- a/sysdeps/unix/sysv/linux/i386/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libpthread.abilist
@@ -216,6 +216,8 @@ GLIBC_2.2.3 GLIBC_2.2.3 A
GLIBC_2.2.3 pthread_getattr_np F
GLIBC_2.2.6 GLIBC_2.2.6 A
GLIBC_2.2.6 __nanosleep F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 pthread_create F
GLIBC_2.3.2 GLIBC_2.3.2 A
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/x86/Versions b/sysdeps/unix/sysv/linux/x86/Versions
new file mode 100644
index 0000000..7f26fa0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/Versions
@@ -0,0 +1,5 @@
+libpthread {
+ GLIBC_2.27 {
+ __pthread_create;
+ }
+}
diff --git a/sysdeps/unix/sysv/linux/x86/nptl/pthreadP.h b/sysdeps/unix/sysv/linux/x86/nptl/pthreadP.h
index 247a62e..a3076bf 100644
--- a/sysdeps/unix/sysv/linux/x86/nptl/pthreadP.h
+++ b/sysdeps/unix/sysv/linux/x86/nptl/pthreadP.h
@@ -23,7 +23,7 @@
extern struct pthread_unwind_buf ____pthread_unwind_buf_private;
-_Static_assert (sizeof (____pthread_unwind_buf_private.cancel_jmp_buf)
+_Static_assert (sizeof (____pthread_unwind_buf_private.updated.cancel_jmp_buf)
>= sizeof (struct __jmp_buf_tag),
"size of cancel_jmp_buf < sizeof __jmp_buf_tag");
diff --git a/sysdeps/unix/sysv/linux/x86/pthread_create.c b/sysdeps/unix/sysv/linux/x86/pthread_create.c
new file mode 100644
index 0000000..699491b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86/pthread_create.c
@@ -0,0 +1,42 @@
+/* X86 versions of pthread_create in libpthread.
+ 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 <nptl/pthread_create.c>
+
+versioned_symbol (libpthread, __pthread_create_2_1, pthread_create,
+ GLIBC_2_27);
+
+#if SHLIB_COMPAT (libpthread, GLIBC_2_1, GLIBC_2_27)
+int
+__pthread_create_compat (pthread_t *newthread,
+ const pthread_attr_t *attr,
+ void *(*start_routine) (void *),
+ void *arg)
+{
+ struct pthread *self = THREAD_SELF;
+ unsigned int feature_1 = THREAD_GETMEM (self, header.feature_1);
+
+ /* Applications compiled against header files older than glibc 2.27
+ use the compatible struct __cancel_jmp_buf_tag. */
+ THREAD_SETMEM (self, header.feature_1, feature_1 | (1 << 2));
+
+ return __pthread_create_2_1 (newthread, attr, start_routine, arg);
+}
+compat_symbol (libpthread, __pthread_create_compat, pthread_create,
+ GLIBC_2_1);
+#endif
diff --git a/sysdeps/unix/sysv/linux/x86/pthreaddef.h b/sysdeps/unix/sysv/linux/x86/pthreaddef.h
index a405a65..e4d4033 100644
--- a/sysdeps/unix/sysv/linux/x86/pthreaddef.h
+++ b/sysdeps/unix/sysv/linux/x86/pthreaddef.h
@@ -20,3 +20,10 @@
/* Need saved_mask in cancel_jmp_buf. */
#define NEED_SAVED_MASK_IN_CANCEL_JMP_BUF 1
+
+#undef unwind_buf_priv
+#define unwind_buf_priv(self,p) \
+ (__extension__ ({ \
+ unsigned int feature_1 = THREAD_GETMEM (self, header.feature_1); \
+ (((feature_1 | (1 << 2)) != 0) \
+ ? &((p)->compat.priv) : &((p)->updated.priv));}))
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
index 85365c0..b14f922 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
@@ -203,6 +203,8 @@ GLIBC_2.2.5 waitpid F
GLIBC_2.2.5 write F
GLIBC_2.2.6 GLIBC_2.2.6 A
GLIBC_2.2.6 __nanosleep F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 pthread_create F
GLIBC_2.3.2 GLIBC_2.3.2 A
GLIBC_2.3.2 pthread_cond_broadcast F
GLIBC_2.3.2 pthread_cond_destroy F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
index 6cd0fc3..688c44d 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
@@ -224,3 +224,5 @@ GLIBC_2.16 write F
GLIBC_2.18 GLIBC_2.18 A
GLIBC_2.18 pthread_getattr_default_np F
GLIBC_2.18 pthread_setattr_default_np F
+GLIBC_2.27 GLIBC_2.27 A
+GLIBC_2.27 pthread_create F
diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h
index 7f0b292..724d8c1 100644
--- a/sysdeps/x86_64/nptl/tls.h
+++ b/sysdeps/x86_64/nptl/tls.h
@@ -58,6 +58,7 @@ typedef struct
# endif
/* Bit 0: IBT.
Bit 1: SHSTK.
+ Bit 2: Compatible struct __cancel_jmp_buf_tag before glibc 2.27.
*/
unsigned int feature_1;
/* Reservation of some values for the TM ABI. */
-----------------------------------------------------------------------
hooks/post-receive
--
GNU C Library master sources