summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-08-14 07:38:41 +0000
committerJakub Jelinek <jakub@redhat.com>2007-08-14 07:38:41 +0000
commitc67c02731b6507c5351bca70451441d9a26113ef (patch)
treeafe8d99e55401fe7955475ab97a497cae2e23ab2
parent39762d6a5c0e378f20b28da7450868bfef588fb0 (diff)
Updated to fedora-glibc-20070814T0725cvs/fedora-glibc-2_6_90-9
-rw-r--r--ChangeLog185
-rw-r--r--csu/libc-start.c12
-rw-r--r--elf/cache.c460
-rw-r--r--elf/dl-dst.h8
-rw-r--r--elf/dl-misc.c8
-rw-r--r--elf/ldconfig.c148
-rw-r--r--elf/readelflib.c6
-rw-r--r--elf/readlib.c29
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in12
-rw-r--r--include/stdio.h7
-rw-r--r--libio/oldtmpfile.c5
-rw-r--r--manual/stdio.texi5
-rw-r--r--misc/Makefile3
-rw-r--r--misc/Versions3
-rw-r--r--misc/mkdtemp.c4
-rw-r--r--misc/mkostemp.c36
-rw-r--r--misc/mkostemp64.c33
-rw-r--r--misc/mkstemp.c4
-rw-r--r--misc/mkstemp64.c5
-rw-r--r--misc/mktemp.c4
-rw-r--r--nptl/ChangeLog192
-rw-r--r--nptl/allocatestack.c1
-rw-r--r--nptl/init.c1
-rw-r--r--nptl/pthreadP.h15
-rw-r--r--nptl/pthread_cond_broadcast.c21
-rw-r--r--nptl/pthread_cond_destroy.c18
-rw-r--r--nptl/pthread_cond_signal.c15
-rw-r--r--nptl/pthread_cond_timedwait.c22
-rw-r--r--nptl/pthread_cond_wait.c34
-rw-r--r--nptl/pthread_create.c1
-rw-r--r--nptl/pthread_mutex_init.c10
-rw-r--r--nptl/pthread_mutex_lock.c35
-rw-r--r--nptl/pthread_mutex_setprioceiling.c11
-rw-r--r--nptl/pthread_mutex_timedlock.c21
-rw-r--r--nptl/pthread_mutex_trylock.c10
-rw-r--r--nptl/pthread_mutex_unlock.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h17
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S60
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S41
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S159
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S156
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i786/Implies2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h12
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h9
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c (renamed from sysdeps/unix/sysv/linux/powerpc/dl-vdso.h)20
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h17
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S35
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S29
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S52
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S86
-rw-r--r--nscd/connections.c27
-rw-r--r--nscd/gai.c2
-rw-r--r--nscd/servicescache.c1
-rw-r--r--nss/Makefile5
-rw-r--r--nss/nss_files/files-XXX.c51
-rw-r--r--nss/nss_files/files-alias.c51
-rw-r--r--nss/nss_files/files-have_o_cloexec.c24
-rw-r--r--shadow/lckpwdf.c42
-rw-r--r--stdio-common/tempnam.c4
-rw-r--r--stdio-common/tempname.c5
-rw-r--r--stdio-common/tmpfile.c15
-rw-r--r--stdio-common/tmpfile64.c4
-rw-r--r--stdio-common/tmpnam.c4
-rw-r--r--stdio-common/tmpnam_r.c4
-rw-r--r--stdlib/stdlib.h22
-rw-r--r--sysdeps/generic/ldconfig.h21
-rw-r--r--sysdeps/mach/hurd/bits/ioctls.h17
-rw-r--r--sysdeps/posix/tempname.c18
-rw-r--r--sysdeps/unix/clock_settime.c6
-rw-r--r--sysdeps/unix/sysv/linux/clock_gettime.c10
-rw-r--r--sysdeps/unix/sysv/linux/dl-osinfo.h1
-rw-r--r--sysdeps/unix/sysv/linux/dl-vdso.c (renamed from sysdeps/unix/sysv/linux/powerpc/dl-vdso.c)15
-rw-r--r--sysdeps/unix/sysv/linux/dl-vdso.h49
-rw-r--r--sysdeps/unix/sysv/linux/fstatfs64.c4
-rw-r--r--sysdeps/unix/sysv/linux/fxstatat.c3
-rw-r--r--sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h4
-rw-r--r--sysdeps/unix/sysv/linux/if_index.c3
-rw-r--r--sysdeps/unix/sysv/linux/ifaddrs.c1
-rw-r--r--sysdeps/unix/sysv/linux/kernel-features.h50
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h2
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/libc-start.c65
-rw-r--r--sysdeps/unix/sysv/linux/ppoll.c4
-rw-r--r--sysdeps/unix/sysv/linux/pselect.c4
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/mmap.S3
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S3
-rw-r--r--sysdeps/unix/sysv/linux/shm_open.c2
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c2
-rw-r--r--sysdeps/unix/sysv/linux/statfs64.c3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/Makefile4
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/Versions3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h35
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/gettimeofday.S7
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/libc-start.c49
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sysdep.h210
-rw-r--r--sysdeps/unix/sysv/linux/xstatconv.c4
112 files changed, 2332 insertions, 705 deletions
diff --git a/ChangeLog b/ChangeLog
index 4f72b85bf0..819ac7e399 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,189 @@
+2007-08-13 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_PSELECT,
+ __ASSUME_PPOLL, __ASSUME_ATFCTS, __ASSUME_SET_ROBUST_LIST,
+ __ASSUME_UTIMENSAT, __ASSUME_FALLOCATE): Update per-arch conditions
+ when each feature was introduced.
+
+ * sysdeps/unix/sysv/linux/dl-vdso.c: Don't include dl-hash.h.
+ * sysdeps/unix/sysv/linux/dl-vdso.h: Don't include dl-hash.h if NDEBUG.
+ (CHECK_HASH): New macro.
+ (PREPARE_VERSION): Use it.
+
+ * sysdeps/unix/sysv/linux/pselect.c (__generic_pselect): Only provide
+ prototype if not __ASSUME_PSELECT.
+ * sysdeps/unix/sysv/linux/ppoll.c (__generic_ppoll): Only provide
+ prototype if not __ASSUME_PPOLL.
+
+ * sysdeps/unix/sysv/linux/dl-osinfo.h (ROUND): #undef after use.
+
+ * sysdeps/unix/clock_settime.c (freq, __pthread_clock_settime,
+ hp_timing_settime): Don't define or declare if HANDLED_CPUTIME
+ is defined.
+
+2007-08-13 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/x86_64/libc-start.c
+ (_libc_vdso_platform_setup): If vDSO is not available point
+ __vdso_gettimeofday to the vsyscall.
+ * sysdeps/unix/sysv/linux/x86_64/gettimeofday.S [SHARED]: Use
+ __vdso_gettimeofday instead of vsyscall.
+
+2007-08-13 Jakub Jelinek <jakub@redhat.com>
+
+ * nscd/servicescache.c: Include kernel-features.h.
+ * nscd/gai.c: Likewise.
+ * sysdeps/unix/sysv/linux/statfs64.c: Likewise.
+ * sysdeps/unix/sysv/linux/fstatfs64.c: Likewise.
+ * sysdeps/unix/sysv/linux/fxstatat.c: Likewise.
+ * sysdeps/unix/sysv/linux/s390/s390-32/mmap.S: Likewise.
+ * sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S: Likewise.
+ * sysdeps/unix/sysv/linux/xstatconv.c: Likewise.
+ * sysdeps/unix/sysv/linux/if_index.c: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c: Likewise.
+ * sysdeps/unix/sysv/linux/ifaddrs.c: Likewise.
+
+2007-08-12 Ulrich Drepper <drepper@redhat.com>
+
+ * elf/dl-dst.h: No need for _dl_dst_count, _dl_dst_substitute,
+ and _dl_get_origin defines anymore.
+
+ * sysdeps/unix/sysv/linux/clock_gettime.c (maybe_syscall_gettime_cpu):
+ Build fix for systems which might lack POSIX timer support.
+
+ * sysdeps/unix/sysv/linux/x86_64/libc-start.c
+ (_libc_vdso_platform_setup): Mangle function pointers before storing
+ them.
+ * sysdeps/unix/sysv/linux/x86_64/sysdep.h (INLINE_VSYSCALL):
+ Demangle vdso pointer before use.
+ (INTERNAL_VSYSCALL): Likewise.
+
+ * elf/cache.c (primes): Mark as const.
+ Noted by Roland McGrath.
+
+2007-08-01 Andreas Jaeger <aj@suse.de>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * elf/ldconfig.c (opt_ignore_aux_cache): Add new option.
+ (options): Add option.
+ (parse_opt): Handle option.
+ (manual_link): Adjust process_file caller. Call implicit_soname.
+ (search_dir): Formatting. Use and populate auxiliary cache.
+ (main): Load and save auxiliary cache.
+ * elf/readlib.c (process_file): Add stat_buf argument. Pass struct
+ stat64 from fstat64 to caller.
+ (implicit_soname): New function.
+ * elf/readelflib.c (process_elf_file): If DT_SONAME is not present,
+ leave *soname as NULL.
+ * elf/cache.c: Include libgen.h.
+ (print_entry, print_cache, compare, save_cache, add_to_cache):
+ Formatting and cleanups.
+ (aux_cache_entry_id, aux_cache_entry, aux_cache_file_entry,
+ aux_cache_file): New structures.
+ (AUX_CACHEMAGIC): Define.
+ (primes): New array.
+ (aux_hash_size, aux_hash): New variables.
+ (aux_cache_entry_id_hash, nextprime, init_aux_cache,
+ search_aux_cache, insert_to_aux_cache, add_to_aux_cache,
+ load_aux_cache, save_aux_cache): New functions.
+ * sysdeps/generic/ldconfig.h (_PATH_LDCONFIG_AUX_CACHE): Define.
+ (init_aux_cache, search_aux_cache, add_to_aux_cache,
+ load_aux_cache, save_aux_cache, implicit_soname): New prototypes.
+ (process_file): Adjust prototype.
+
+2007-08-12 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h: Include stddef.h
+ with __need_size_t.
+
+2007-08-12 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/dl-vdso.c (_dl_vdso_vsym): Expect
+ r_found_version structure as second parameter.
+ * sysdeps/unix/sysv/linux/dl-vdso.h (PREPARE_VERSION): Define.
+ (_dl_vdso_vsym): Change type of second parameter accordingly.
+ * sysdeps/unix/sysv/linux/x86-64/libc-start.c
+ (_libc_vdso_platform_setup): Adjust.
+ * sysdeps/unix/sysv/linux/powerpc/libc-start.c
+ (_libc_vdso_platform_setup): Likewise.
+
+ * sysdeps/unix/sysv/linux/powerpc/dl-vdso.c: Move to...
+ * sysdeps/unix/sysv/linux/dl-vdso.c: ...here.
+ * sysdeps/unix/sysv/linux/powerpc/dl-vdso.h: Move to...
+ * sysdeps/unix/sysv/linux/dl-vdso.h: ...here.
+ * csu/libc-start.c: Pretty printing.
+ Use VDSO_SETUP if defined.
+ * sysdeps/unix/sysv/linux/powerpc/libc-start.c: Define VDSO_SETUP
+ and let generic code call into _libc_vdso_platform_setup.
+ * sysdeps/unix/sysv/linux/x86_64/libc-start.c: New file.
+ * sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: New file.
+ * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Pretty printing.
+ Define INLINE_VSYSCALL and INTERNAL_VSYSCALL.
+ * sysdeps/unix/sysv/linux/x86_64/Versions: Export __vdso_clock_gettime
+ for GLIBC_PRIVATE.
+ * sysdeps/unix/sysv/linux/x86_64/Makefile [subdir=elf]
+ (sysdep_rountines): Add dl-vdso.
+
+ * sysdeps/unix/sysv/linux/powerpc/Makefile: Use sysdep_routines instead
+ of routines.
+
+ * sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h: Add
+ attribute_hidden to __vdso_gettimeofday prototype.
+
+2007-08-12 Roland McGrath <roland@redhat.com>
+
+ * manual/stdio.texi (Variable Arguments Output): Fix xref to gcc manual.
+ From: Karl Berry <karl@freefriends.org>.
+
+2007-08-11 Ulrich Drepper <drepper@redhat.com>
+
+ * elf/dl-misc.c (_dl_sysdep_read_whole_file): We really don't need
+ an atime update for the files we read.
+
2007-08-10 Ulrich Drepper <drepper@redhat.com>
- * sysdeps/unix/sysv/linux/shm_open.c (shm_open): Use O_CLOEXEC is
+ * shadow/lckpwdf.c (__lckpwdf): Use O_CLOEXEC if possible.
+
+ * nscd/connections.c: Use O_CLOEXEC if possible. Use mkostemp
+ instead of mkstemp.
+
+ * misc/Makefile (routines): Add mkostemp and mkostemp64.
+ * misc/Versions: Export mkostemp and mkostemp64 for GLIBC_2.7.
+ * misc/mkostemp.c: New file.
+ * misc/mkostemp64.c: New file.
+ * stdlib/stdlib.h: Declare the new functions.
+ * sysdeps/posix/tempname.c: Add new parameter which is added to
+ the flags for open. Remove __GT_BIGFILE handling.
+ * stdio-common/tempname.c: Likewise.
+ * include/stdio.h: Adjust __gen_tempname prototype.
+ Renumber __GT_* constants.
+ * libio/oldtmpfile.c: Adjust for __gen_tempname interface change.
+ * misc/mkdtemp.c: Likewise.
+ * misc/mkstemp.c: Likewise.
+ * misc/mkstemp64.c: Likewise.
+ * misc/mktemp.c: Likewise.
+ * stdio-common/tempnam.c: Likewise.
+ * stdio-common/tmpfile.c: Likewise.
+ * stdio-common/tmpfile64.c: Likewise.
+ * stdio-common/tmpnam.c: Likewise.
+ * stdio-common/tmpnam_r.c: Likewise.
+
+2007-08-10 Roland McGrath <roland@frob.com>
+
+ * sysdeps/mach/hurd/bits/ioctls.h (NLDLY, TABDLY, BSDLY, VTDLY):
+ New macros.
+ (NLDELAY, CRDELAY, TBDELAY, BSDELAY, VTDELAY): Define to those.
+ Reported by Samuel Thibault <samuel.thibault@ens-lyon.org>.
+
+2007-08-10 Ulrich Drepper <drepper@redhat.com>
+
+ * nss/nss_files/files-XXX.c (internal_setent): Use O_CLOEXEC if
+ possible.
+ * nss/nss_files/files-alias.c (internal_setent): Likewise.
+ * nss/Makefile (libnss_files-routines): Add files-have_o_cloexec.
+ * nss/nss_files/files-have_o_cloexec.c: New file.
+
+ * sysdeps/unix/sysv/linux/shm_open.c (shm_open): Use O_CLOEXEC if
available.
2007-08-10 Jakub Jelinek <jakub@redhat.com>
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 0ed993651e..d3eadeb704 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -138,16 +138,18 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
functions are using thread functions if these are available and
we need to setup errno. */
__pthread_initialize_minimal ();
-#endif
-# ifndef SHARED
/* Set up the stack checker's canary. */
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
-# ifdef THREAD_SET_STACK_GUARD
+# ifdef THREAD_SET_STACK_GUARD
THREAD_SET_STACK_GUARD (stack_chk_guard);
-# else
+# else
__stack_chk_guard = stack_chk_guard;
-# endif
+# endif
+#endif
+
+#ifdef VDSO_SETUP
+ VDSO_SETUP ();
#endif
/* Register the destructor of the dynamic linker if there is any. */
diff --git a/elf/cache.c b/elf/cache.c
index 6dbd5a6c08..9a600ea535 100644
--- a/elf/cache.c
+++ b/elf/cache.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2003,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2003,2005,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 1999.
@@ -20,6 +20,7 @@
#include <error.h>
#include <dirent.h>
#include <inttypes.h>
+#include <libgen.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -80,16 +81,16 @@ print_entry (const char *lib, int flag, unsigned int osversion,
fputs (",x86-64", stdout);
break;
case FLAG_S390_LIB64:
- fputs(",64bit", stdout);
+ fputs (",64bit", stdout);
break;
case FLAG_POWERPC_LIB64:
- fputs(",64bit", stdout);
+ fputs (",64bit", stdout);
break;
case FLAG_MIPS64_LIBN32:
- fputs(",N32", stdout);
+ fputs (",N32", stdout);
break;
case FLAG_MIPS64_LIBN64:
- fputs(",64bit", stdout);
+ fputs (",64bit", stdout);
case 0:
break;
default:
@@ -128,19 +129,11 @@ print_entry (const char *lib, int flag, unsigned int osversion,
void
print_cache (const char *cache_name)
{
- size_t cache_size;
- struct stat64 st;
- int fd;
- unsigned int i;
- struct cache_file *cache;
- struct cache_file_new *cache_new = NULL;
- const char *cache_data;
- int format = 0;
-
- fd = open (cache_name, O_RDONLY);
+ int fd = open (cache_name, O_RDONLY);
if (fd < 0)
error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name);
+ struct stat64 st;
if (fstat64 (fd, &st) < 0
/* No need to map the file if it is empty. */
|| st.st_size == 0)
@@ -149,14 +142,19 @@ print_cache (const char *cache_name)
return;
}
- cache = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ struct cache_file *cache
+ = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (cache == MAP_FAILED)
error (EXIT_FAILURE, errno, _("mmap of cache file failed.\n"));
- cache_size = st.st_size;
+ size_t cache_size = st.st_size;
if (cache_size < sizeof (struct cache_file))
error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
+ struct cache_file_new *cache_new = NULL;
+ const char *cache_data;
+ int format = 0;
+
if (memcmp (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1))
{
/* This can only be the new format without the old one. */
@@ -201,7 +199,7 @@ print_cache (const char *cache_name)
printf (_("%d libs found in cache `%s'\n"), cache->nlibs, cache_name);
/* Print everything. */
- for (i = 0; i < cache->nlibs; i++)
+ for (unsigned int i = 0; i < cache->nlibs; i++)
print_entry (cache_data + cache->libs[i].key,
cache->libs[i].flags, 0, 0,
cache_data + cache->libs[i].value);
@@ -212,7 +210,7 @@ print_cache (const char *cache_name)
cache_new->nlibs, cache_name);
/* Print everything. */
- for (i = 0; i < cache_new->nlibs; i++)
+ for (unsigned int i = 0; i < cache_new->nlibs; i++)
print_entry (cache_data + cache_new->libs[i].key,
cache_new->libs[i].flags,
cache_new->libs[i].osversion,
@@ -231,15 +229,11 @@ init_cache (void)
entries = NULL;
}
-
-
-static
-int compare (const struct cache_entry *e1, const struct cache_entry *e2)
+static int
+compare (const struct cache_entry *e1, const struct cache_entry *e2)
{
- int res;
-
/* We need to swap entries here to get the correct sort order. */
- res = _dl_cache_libcmp (e2->lib, e1->lib);
+ int res = _dl_cache_libcmp (e2->lib, e1->lib);
if (res == 0)
{
if (e1->flags < e2->flags)
@@ -267,29 +261,19 @@ int compare (const struct cache_entry *e1, const struct cache_entry *e2)
void
save_cache (const char *cache_name)
{
- struct cache_entry *entry;
- int fd, idx_old, idx_new;
- size_t total_strlen, len;
- char *strings, *str, *temp_name;
- struct cache_file *file_entries = NULL;
- struct cache_file_new *file_entries_new = NULL;
- size_t file_entries_size = 0;
- size_t file_entries_new_size = 0;
- unsigned int str_offset;
- /* Number of cache entries. */
- int cache_entry_count = 0;
- /* Number of normal cache entries. */
- int cache_entry_old_count = 0;
- /* Pad for alignment of cache_file_new. */
- size_t pad;
-
/* The cache entries are sorted already, save them in this order. */
/* Count the length of all strings. */
/* The old format doesn't contain hwcap entries and doesn't contain
libraries in subdirectories with hwcaps entries. Count therefore
also all entries with hwcap == 0. */
- total_strlen = 0;
+ size_t total_strlen = 0;
+ struct cache_entry *entry;
+ /* Number of cache entries. */
+ int cache_entry_count = 0;
+ /* Number of normal cache entries. */
+ int cache_entry_old_count = 0;
+
for (entry = entries; entry != NULL; entry = entry->next)
{
/* Account the final NULs. */
@@ -300,8 +284,8 @@ save_cache (const char *cache_name)
}
/* Create the on disk cache structure. */
- /* First an array for all strings. */
- strings = (char *)xmalloc (total_strlen);
+ struct cache_file *file_entries = NULL;
+ size_t file_entries_size = 0;
if (opt_format != 2)
{
@@ -315,25 +299,27 @@ save_cache (const char *cache_name)
/* And the list of all entries in the old format. */
file_entries_size = sizeof (struct cache_file)
+ cache_entry_old_count * sizeof (struct file_entry);
- file_entries = (struct cache_file *) xmalloc (file_entries_size);
+ file_entries = xmalloc (file_entries_size);
/* Fill in the header. */
- memset (file_entries, 0, sizeof (struct cache_file));
+ memset (file_entries, '\0', sizeof (struct cache_file));
memcpy (file_entries->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1);
file_entries->nlibs = cache_entry_old_count;
}
+ struct cache_file_new *file_entries_new = NULL;
+ size_t file_entries_new_size = 0;
+
if (opt_format != 0)
{
/* And the list of all entries in the new format. */
file_entries_new_size = sizeof (struct cache_file_new)
+ cache_entry_count * sizeof (struct file_entry_new);
- file_entries_new =
- (struct cache_file_new *) xmalloc (file_entries_new_size);
+ file_entries_new = xmalloc (file_entries_new_size);
/* Fill in the header. */
- memset (file_entries_new, 0, sizeof (struct cache_file_new));
+ memset (file_entries_new, '\0', sizeof (struct cache_file_new));
memcpy (file_entries_new->magic, CACHEMAGIC_NEW,
sizeof CACHEMAGIC_NEW - 1);
memcpy (file_entries_new->version, CACHE_VERSION,
@@ -343,17 +329,24 @@ save_cache (const char *cache_name)
file_entries_new->len_strings = total_strlen;
}
- pad = ALIGN_CACHE (file_entries_size) - file_entries_size;
+ /* Pad for alignment of cache_file_new. */
+ size_t pad = ALIGN_CACHE (file_entries_size) - file_entries_size;
/* If we have both formats, we hide the new format in the strings
table, we have to adjust all string indices for this so that
old libc5/glibc 2 dynamic linkers just ignore them. */
+ unsigned int str_offset;
if (opt_format != 0)
str_offset = file_entries_new_size;
else
str_offset = 0;
- str = strings;
+ /* An array for all strings. */
+ char *strings = xmalloc (total_strlen);
+ char *str = strings;
+ int idx_old;
+ int idx_new;
+
for (idx_old = 0, idx_new = 0, entry = entries; entry != NULL;
entry = entry->next, ++idx_new)
{
@@ -375,21 +368,18 @@ save_cache (const char *cache_name)
file_entries_new->libs[idx_new].hwcap = entry->hwcap;
file_entries_new->libs[idx_new].key = str_offset;
}
- len = strlen (entry->lib);
- str = stpcpy (str, entry->lib);
- /* Account the final NUL. */
- ++str;
- str_offset += len + 1;
+
+ size_t len = strlen (entry->lib) + 1;
+ str = mempcpy (str, entry->lib, len);
+ str_offset += len;
/* Then the path. */
if (opt_format != 2 && entry->hwcap == 0)
file_entries->libs[idx_old].value = str_offset + pad;
if (opt_format != 0)
file_entries_new->libs[idx_new].value = str_offset;
- len = strlen (entry->path);
- str = stpcpy (str, entry->path);
- /* Account the final NUL. */
- ++str;
- str_offset += len + 1;
+ len = strlen (entry->path) + 1;
+ str = mempcpy (str, entry->path, len);
+ str_offset += len;
/* Ignore entries with hwcap for old format. */
if (entry->hwcap == 0)
++idx_old;
@@ -403,16 +393,12 @@ save_cache (const char *cache_name)
/* Write out the cache. */
/* Write cache first to a temporary file and rename it later. */
- temp_name = xmalloc (strlen (cache_name) + 2);
+ char *temp_name = xmalloc (strlen (cache_name) + 2);
sprintf (temp_name, "%s~", cache_name);
- /* First remove an old copy if it exists. */
- if (unlink (temp_name) && errno != ENOENT)
- error (EXIT_FAILURE, errno, _("Can't remove old temporary cache file %s"),
- temp_name);
/* Create file. */
- fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
- S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR);
+ int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
+ S_IRUSR|S_IWUSR);
if (fd < 0)
error (EXIT_FAILURE, errno, _("Can't create temporary cache file %s"),
temp_name);
@@ -439,11 +425,10 @@ save_cache (const char *cache_name)
error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
}
- if (write (fd, strings, total_strlen) != (ssize_t) total_strlen)
+ if (write (fd, strings, total_strlen) != (ssize_t) total_strlen
+ || close (fd))
error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
- close (fd);
-
/* Make sure user can always read cache file */
if (chmod (temp_name, S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR))
error (EXIT_FAILURE, errno,
@@ -463,8 +448,6 @@ save_cache (const char *cache_name)
while (entries)
{
entry = entries;
- free (entry->path);
- free (entry->lib);
entries = entries->next;
free (entry);
}
@@ -476,33 +459,29 @@ void
add_to_cache (const char *path, const char *lib, int flags,
unsigned int osversion, uint64_t hwcap)
{
- struct cache_entry *new_entry, *ptr, *prev;
- char *full_path;
- size_t len, i;
-
- new_entry = (struct cache_entry *) xmalloc (sizeof (struct cache_entry));
-
- len = strlen (lib) + strlen (path) + 2;
-
- full_path = (char *) xmalloc (len);
- snprintf (full_path, len, "%s/%s", path, lib);
-
- new_entry->lib = xstrdup (lib);
- new_entry->path = full_path;
+ size_t liblen = strlen (lib) + 1;
+ size_t len = liblen + strlen (path) + 1;
+ struct cache_entry *new_entry
+ = xmalloc (sizeof (struct cache_entry) + liblen + len);
+
+ new_entry->lib = memcpy ((char *) (new_entry + 1), lib, liblen);
+ new_entry->path = new_entry->lib + liblen;
+ snprintf (new_entry->path, len, "%s/%s", path, lib);
new_entry->flags = flags;
new_entry->osversion = osversion;
new_entry->hwcap = hwcap;
new_entry->bits_hwcap = 0;
/* Count the number of bits set in the masked value. */
- for (i = 0; (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i)
+ for (size_t i = 0;
+ (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i)
if ((hwcap & (1ULL << i)) != 0)
++new_entry->bits_hwcap;
/* Keep the list sorted - search for right place to insert. */
- ptr = entries;
- prev = entries;
+ struct cache_entry *ptr = entries;
+ struct cache_entry *prev = entries;
while (ptr != NULL)
{
if (compare (ptr, new_entry) > 0)
@@ -522,3 +501,304 @@ add_to_cache (const char *path, const char *lib, int flags,
prev->next = new_entry;
}
}
+
+
+/* Auxiliary cache. */
+
+struct aux_cache_entry_id
+{
+ uint64_t ino;
+ uint64_t ctime;
+ uint64_t size;
+ uint64_t dev;
+};
+
+struct aux_cache_entry
+{
+ struct aux_cache_entry_id id;
+ int flags;
+ unsigned int osversion;
+ int used;
+ char *soname;
+ struct aux_cache_entry *next;
+};
+
+#define AUX_CACHEMAGIC "glibc-ld.so.auxcache-1.0"
+
+struct aux_cache_file_entry
+{
+ struct aux_cache_entry_id id; /* Unique id of entry. */
+ int32_t flags; /* This is 1 for an ELF library. */
+ uint32_t soname; /* String table indice. */
+ uint32_t osversion; /* Required OS version. */
+ int32_t pad;
+};
+
+/* ldconfig maintains an auxiliary cache file that allows
+ only reading those libraries that have changed since the last iteration.
+ For this for each library some information is cached in the auxiliary
+ cache. */
+struct aux_cache_file
+{
+ char magic[sizeof AUX_CACHEMAGIC - 1];
+ uint32_t nlibs; /* Number of entries. */
+ uint32_t len_strings; /* Size of string table. */
+ struct aux_cache_file_entry libs[0]; /* Entries describing libraries. */
+ /* After this the string table of size len_strings is found. */
+};
+
+static const unsigned int primes[] =
+{
+ 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139,
+ 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393,
+ 67108859, 134217689, 268435399, 536870909, 1073741789, 2147483647
+};
+
+static size_t aux_hash_size;
+static struct aux_cache_entry **aux_hash;
+
+/* Simplistic hash function for aux_cache_entry_id. */
+static unsigned int
+aux_cache_entry_id_hash (struct aux_cache_entry_id *id)
+{
+ uint64_t ret = ((id->ino * 11 + id->ctime) * 11 + id->size) * 11 + id->dev;
+ return ret ^ (ret >> 32);
+}
+
+static size_t nextprime (size_t x)
+{
+ for (unsigned int i = 0; i < sizeof (primes) / sizeof (primes[0]); ++i)
+ if (primes[i] >= x)
+ return primes[i];
+ return x;
+}
+
+void
+init_aux_cache (void)
+{
+ aux_hash_size = primes[3];
+ aux_hash = xcalloc (aux_hash_size, sizeof (struct aux_cache_entry *));
+}
+
+int
+search_aux_cache (struct stat64 *stat_buf, int *flags,
+ unsigned int *osversion, char **soname)
+{
+ struct aux_cache_entry_id id;
+ id.ino = (uint64_t) stat_buf->st_ino;
+ id.ctime = (uint64_t) stat_buf->st_ctime;
+ id.size = (uint64_t) stat_buf->st_size;
+ id.dev = (uint64_t) stat_buf->st_dev;
+
+ unsigned int hash = aux_cache_entry_id_hash (&id);
+ struct aux_cache_entry *entry;
+ for (entry = aux_hash[hash % aux_hash_size]; entry; entry = entry->next)
+ if (id.ino == entry->id.ino
+ && id.ctime == entry->id.ctime
+ && id.size == entry->id.size
+ && id.dev == entry->id.dev)
+ {
+ *flags = entry->flags;
+ *osversion = entry->osversion;
+ if (entry->soname != NULL)
+ *soname = xstrdup (entry->soname);
+ else
+ *soname = NULL;
+ entry->used = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+insert_to_aux_cache (struct aux_cache_entry_id *id, int flags,
+ unsigned int osversion, const char *soname, int used)
+{
+ size_t hash = aux_cache_entry_id_hash (id) % aux_hash_size;
+ struct aux_cache_entry *entry;
+ for (entry = aux_hash[hash]; entry; entry = entry->next)
+ if (id->ino == entry->id.ino
+ && id->ctime == entry->id.ctime
+ && id->size == entry->id.size
+ && id->dev == entry->id.dev)
+ abort ();
+
+ size_t len = soname ? strlen (soname) + 1 : 0;
+ entry = xmalloc (sizeof (struct aux_cache_entry) + len);
+ entry->id = *id;
+ entry->flags = flags;
+ entry->osversion = osversion;
+ entry->used = used;
+ if (soname != NULL)
+ entry->soname = memcpy ((char *) (entry + 1), soname, len);
+ else
+ entry->soname = NULL;
+ entry->next = aux_hash[hash];
+ aux_hash[hash] = entry;
+}
+
+void
+add_to_aux_cache (struct stat64 *stat_buf, int flags,
+ unsigned int osversion, const char *soname)
+{
+ struct aux_cache_entry_id id;
+ id.ino = (uint64_t) stat_buf->st_ino;
+ id.ctime = (uint64_t) stat_buf->st_ctime;
+ id.size = (uint64_t) stat_buf->st_size;
+ id.dev = (uint64_t) stat_buf->st_dev;
+ insert_to_aux_cache (&id, flags, osversion, soname, 1);
+}
+
+/* Load auxiliary cache to search for unchanged entries. */
+void
+load_aux_cache (const char *aux_cache_name)
+{
+ int fd = open (aux_cache_name, O_RDONLY);
+ if (fd < 0)
+ {
+ init_aux_cache ();
+ return;
+ }
+
+ struct stat64 st;
+ if (fstat64 (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file))
+ {
+ close (fd);
+ init_aux_cache ();
+ return;
+ }
+
+ size_t aux_cache_size = st.st_size;
+ struct aux_cache_file *aux_cache
+ = mmap (NULL, aux_cache_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (aux_cache == MAP_FAILED
+ || aux_cache_size < sizeof (struct aux_cache_file)
+ || memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1)
+ || aux_cache->nlibs < 0
+ || aux_cache->nlibs >= aux_cache_size)
+ {
+ close (fd);
+ init_aux_cache ();
+ return;
+ }
+
+ aux_hash_size = nextprime (aux_cache->nlibs);
+ aux_hash = xcalloc (aux_hash_size, sizeof (struct aux_cache_entry *));
+
+ const char *aux_cache_data
+ = (const char *) &aux_cache->libs[aux_cache->nlibs];
+ for (unsigned int i = 0; i < aux_cache->nlibs; ++i)
+ insert_to_aux_cache (&aux_cache->libs[i].id,
+ aux_cache->libs[i].flags,
+ aux_cache->libs[i].osversion,
+ aux_cache->libs[i].soname == 0
+ ? NULL : aux_cache_data + aux_cache->libs[i].soname,
+ 0);
+
+ munmap (aux_cache, aux_cache_size);
+ close (fd);
+}
+
+/* Save the contents of the auxiliary cache. */
+void
+save_aux_cache (const char *aux_cache_name)
+{
+ /* Count the length of all sonames. We start with empty string. */
+ size_t total_strlen = 1;
+ /* Number of cache entries. */
+ int cache_entry_count = 0;
+
+ for (size_t i = 0; i < aux_hash_size; ++i)
+ for (struct aux_cache_entry *entry = aux_hash[i];
+ entry != NULL; entry = entry->next)
+ if (entry->used)
+ {
+ ++cache_entry_count;
+ if (entry->soname != NULL)
+ total_strlen += strlen (entry->soname) + 1;
+ }
+
+ /* Auxiliary cache. */
+ size_t file_entries_size
+ = sizeof (struct aux_cache_file)
+ + cache_entry_count * sizeof (struct aux_cache_file_entry);
+ struct aux_cache_file *file_entries
+ = xmalloc (file_entries_size + total_strlen);
+
+ /* Fill in the header of the auxiliary cache. */
+ memset (file_entries, '\0', sizeof (struct aux_cache_file));
+ memcpy (file_entries->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1);
+
+ file_entries->nlibs = cache_entry_count;
+ file_entries->len_strings = total_strlen;
+
+ /* Initial String offset for auxiliary cache is always after the
+ special empty string. */
+ unsigned int str_offset = 1;
+
+ /* An array for all strings. */
+ char *str = (char *) file_entries + file_entries_size;
+ *str++ = '\0';
+
+ size_t idx = 0;
+ for (size_t i = 0; i < aux_hash_size; ++i)
+ for (struct aux_cache_entry *entry = aux_hash[i];
+ entry != NULL; entry = entry->next)
+ if (entry->used)
+ {
+ file_entries->libs[idx].id = entry->id;
+ file_entries->libs[idx].flags = entry->flags;
+ if (entry->soname == NULL)
+ file_entries->libs[idx].soname = 0;
+ else
+ {
+ file_entries->libs[idx].soname = str_offset;
+
+ size_t len = strlen (entry->soname) + 1;
+ str = mempcpy (str, entry->soname, len);
+ str_offset += len;
+ }
+ file_entries->libs[idx].osversion = entry->osversion;
+ file_entries->libs[idx++].pad = 0;
+ }
+
+ /* Write out auxiliary cache file. */
+ /* Write auxiliary cache first to a temporary file and rename it later. */
+
+ char *temp_name = xmalloc (strlen (aux_cache_name) + 2);
+ sprintf (temp_name, "%s~", aux_cache_name);
+
+ /* Check that directory exists and create if needed. */
+ char *dir = strdupa (aux_cache_name);
+ dir = dirname (dir);
+
+ struct stat64 st;
+ if (stat64 (dir, &st) < 0)
+ {
+ if (mkdir (dir, 0700) < 0)
+ goto out_fail;
+ }
+
+ /* Create file. */
+ int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
+ S_IRUSR|S_IWUSR);
+ if (fd < 0)
+ goto out_fail;
+
+ if (write (fd, file_entries, file_entries_size + total_strlen)
+ != (ssize_t) (file_entries_size + total_strlen)
+ || close (fd))
+ {
+ unlink (temp_name);
+ goto out_fail;
+ }
+
+ /* Move temporary to its final location. */
+ if (rename (temp_name, aux_cache_name))
+ unlink (temp_name);
+
+out_fail:
+ /* Free allocated memory. */
+ free (file_entries);
+}
diff --git a/elf/dl-dst.h b/elf/dl-dst.h
index 175b7cd195..76076a6036 100644
--- a/elf/dl-dst.h
+++ b/elf/dl-dst.h
@@ -29,9 +29,6 @@
__cnt = _dl_dst_count (__sf, is_path); \
\
__cnt; })
-#ifndef IS_IN_rtld
-# define _dl_dst_count GLRO(dl_dst_count)
-#endif
/* Guess from the number of DSTs the length of the result string. */
@@ -79,8 +76,3 @@
} \
else
#endif
-
-#ifndef IS_IN_rtld
-# define _dl_get_origin GLRO(dl_get_origin)
-# define _dl_dst_substitute GLRO(dl_dst_substitute)
-#endif
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
index 6da1e2e4aa..41da98d729 100644
--- a/elf/dl-misc.c
+++ b/elf/dl-misc.c
@@ -1,5 +1,5 @@
/* Miscellaneous support functions for dynamic linker
- Copyright (C) 1997-2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1997-2004, 2006, 2007 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
@@ -55,7 +55,11 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
{
void *result = MAP_FAILED;
struct stat64 st;
- int fd = __open (file, O_RDONLY);
+ int oflags = O_RDONLY;
+#ifdef O_NOATIME
+ oflags |= O_NOATIME;
+#endif
+ int fd = __open (file, oflags);
if (fd >= 0)
{
if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index 7692e3a8af..cb1851e4be 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -112,6 +112,9 @@ static char *opt_chroot;
/* Manually link given shared libraries. */
static int opt_manual_link;
+/* Should we ignore an old auxiliary cache file? */
+static int opt_ignore_aux_cache;
+
/* Cache file to use. */
static char *cache_file;
@@ -142,6 +145,7 @@ static const struct argp_option options[] =
{ NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0},
{ NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
{ "format", 'c', N_("FORMAT"), 0, N_("Format to use: new, old or compat (default)"), 0},
+ { "ignore-aux-cache", 'i', NULL, 0, N_("Ignore auxiliary cache file"), 0},
{ NULL, 0, NULL, 0, NULL, 0 }
};
@@ -238,10 +242,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
{
case 'C':
cache_file = arg;
+ /* Ignore auxiliary cache since we use non-standard cache. */
+ opt_ignore_aux_cache = 1;
break;
case 'f':
config_file = arg;
break;
+ case 'i':
+ opt_ignore_aux_cache = 1;
+ break;
case 'l':
opt_manual_link = 1;
break;
@@ -518,7 +527,7 @@ manual_link (char *library)
if (libname)
{
/* Successfully split names. Check if path is just "/" to avoid
- an empty path. */
+ an empty path. */
if (libname == path)
{
libname = library + 1;
@@ -572,14 +581,17 @@ manual_link (char *library)
free (path);
return;
}
+
if (process_file (real_library, library, libname, &flag, &osversion,
- &soname, 0))
+ &soname, 0, &stat_buf))
{
error (0, 0, _("No link created since soname could not be found for %s"),
library);
free (path);
return;
}
+ if (soname == NULL)
+ soname = implicit_soname (libname, flag);
create_links (real_path, path, libname, soname);
free (soname);
free (path);
@@ -625,23 +637,7 @@ struct dlib_entry
static void
search_dir (const struct dir_entry *entry)
{
- DIR *dir;
- struct dirent64 *direntry;
- char *file_name, *dir_name, *real_file_name, *real_name;
- int file_name_len, real_file_name_len, len;
- char *soname;
- struct dlib_entry *dlibs;
- struct dlib_entry *dlib_ptr;
- struct stat64 lstat_buf, stat_buf;
- int is_link, is_dir;
uint64_t hwcap = path_hwcap (entry->path);
- unsigned int osversion;
-
- file_name_len = PATH_MAX;
- file_name = alloca (file_name_len);
-
- dlibs = NULL;
-
if (opt_verbose)
{
if (hwcap != 0)
@@ -650,6 +646,11 @@ search_dir (const struct dir_entry *entry)
printf ("%s:\n", entry->path);
}
+ char *dir_name;
+ char *real_file_name;
+ size_t real_file_name_len;
+ size_t file_name_len = PATH_MAX;
+ char *file_name = alloca (file_name_len);
if (opt_chroot)
{
dir_name = chroot_canon (opt_chroot, entry->path);
@@ -663,6 +664,7 @@ search_dir (const struct dir_entry *entry)
real_file_name = file_name;
}
+ DIR *dir;
if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
{
if (opt_verbose)
@@ -672,6 +674,8 @@ search_dir (const struct dir_entry *entry)
return;
}
+ struct dirent64 *direntry;
+ struct dlib_entry *dlibs = NULL;
while ((direntry = readdir64 (dir)) != NULL)
{
int flag;
@@ -695,7 +699,8 @@ search_dir (const struct dir_entry *entry)
#endif
!is_hwcap_platform (direntry->d_name)))
continue;
- len = strlen (direntry->d_name);
+
+ size_t len = strlen (direntry->d_name);
/* Skip temporary files created by the prelink program. Files with
names like these are never really DSOs we want to look at. */
if (len >= sizeof (".#prelink#") - 1)
@@ -727,7 +732,10 @@ search_dir (const struct dir_entry *entry)
}
sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
}
+
+ struct stat64 lstat_buf;
#ifdef _DIRENT_HAVE_D_TYPE
+ /* We optimize and try to do the lstat call only if needed. */
if (direntry->d_type != DT_UNKNOWN)
lstat_buf.st_mode = DTTOIF (direntry->d_type);
else
@@ -738,9 +746,11 @@ search_dir (const struct dir_entry *entry)
continue;
}
- is_link = S_ISLNK (lstat_buf.st_mode);
+ struct stat64 stat_buf;
+ int is_dir;
+ int is_link = S_ISLNK (lstat_buf.st_mode);
if (is_link)
- {
+ {
/* In case of symlink, we check if the symlink refers to
a directory. */
if (__builtin_expect (stat64 (real_file_name, &stat_buf), 0))
@@ -754,6 +764,12 @@ search_dir (const struct dir_entry *entry)
continue;
}
is_dir = S_ISDIR (stat_buf.st_mode);
+
+ /* lstat_buf is later stored, update contents. */
+ lstat_buf.st_dev = stat_buf.st_dev;
+ lstat_buf.st_ino = stat_buf.st_ino;
+ lstat_buf.st_size = stat_buf.st_size;
+ lstat_buf.st_ctime = stat_buf.st_ctime;
}
else
is_dir = S_ISDIR (lstat_buf.st_mode);
@@ -767,36 +783,28 @@ search_dir (const struct dir_entry *entry)
new_entry->path = xstrdup (file_name);
new_entry->flag = entry->flag;
new_entry->next = NULL;
- if (is_link)
+#ifdef _DIRENT_HAVE_D_TYPE
+ /* We have filled in lstat only #ifndef
+ _DIRENT_HAVE_D_TYPE. Fill it in if needed. */
+ if (!is_link
+ && direntry->d_type != DT_UNKNOWN
+ && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
{
- new_entry->ino = stat_buf.st_ino;
- new_entry->dev = stat_buf.st_dev;
+ error (0, errno, _("Cannot lstat %s"), file_name);
+ free (new_entry->path);
+ free (new_entry);
+ continue;
}
- else
- {
-#ifdef _DIRENT_HAVE_D_TYPE
- /* We have filled in lstat only #ifndef
- _DIRENT_HAVE_D_TYPE. Fill it in if needed. */
- if (direntry->d_type != DT_UNKNOWN
- && __builtin_expect (lstat64 (real_file_name, &lstat_buf),
- 0))
- {
- error (0, errno, _("Cannot lstat %s"), file_name);
- free (new_entry->path);
- free (new_entry);
- continue;
- }
#endif
-
- new_entry->ino = lstat_buf.st_ino;
- new_entry->dev = lstat_buf.st_dev;
- }
+ new_entry->ino = lstat_buf.st_ino;
+ new_entry->dev = lstat_buf.st_dev;
add_single_dir (new_entry, 0);
continue;
}
else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
continue;
+ char *real_name;
if (opt_chroot && is_link)
{
real_name = chroot_canon (opt_chroot, file_name);
@@ -810,14 +818,36 @@ search_dir (const struct dir_entry *entry)
else
real_name = real_file_name;
- if (process_file (real_name, file_name, direntry->d_name, &flag,
- &osversion, &soname, is_link))
+#ifdef _DIRENT_HAVE_D_TYPE
+ /* Call lstat64 if not done yet. */
+ if (!is_link
+ && direntry->d_type != DT_UNKNOWN
+ && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
{
- if (real_name != real_file_name)
- free (real_name);
+ error (0, errno, _("Cannot lstat %s"), file_name);
continue;
}
+#endif
+
+ /* First search whether the auxiliary cache contains this
+ library already and it's not changed. */
+ char *soname;
+ unsigned int osversion;
+ if (!search_aux_cache (&lstat_buf, &flag, &osversion, &soname))
+ {
+ if (process_file (real_name, file_name, direntry->d_name, &flag,
+ &osversion, &soname, is_link, &lstat_buf))
+ {
+ if (real_name != real_file_name)
+ free (real_name);
+ continue;
+ }
+ else if (opt_build_cache)
+ add_to_aux_cache (&lstat_buf, flag, osversion, soname);
+ }
+ if (soname == NULL)
+ soname = implicit_soname (direntry->d_name, flag);
/* A link may just point to itself. */
if (is_link)
@@ -834,7 +864,7 @@ search_dir (const struct dir_entry *entry)
|| strncmp (real_base_name, soname, len) != 0)
is_link = 0;
}
- }
+ }
if (real_name != real_file_name)
free (real_name);
@@ -849,6 +879,7 @@ search_dir (const struct dir_entry *entry)
&& (entry->flag == FLAG_ELF_LIBC5
|| entry->flag == FLAG_ELF_LIBC6))
flag = entry->flag;
+
/* Some sanity checks to print warnings. */
if (opt_verbose)
{
@@ -864,6 +895,7 @@ search_dir (const struct dir_entry *entry)
}
/* Add library to list. */
+ struct dlib_entry *dlib_ptr;
for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
{
/* Is soname already in list? */
@@ -888,12 +920,13 @@ search_dir (const struct dir_entry *entry)
dlib_ptr->flag = flag;
else
error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
- dlib_ptr->name, direntry->d_name, entry->path);
+ dlib_ptr->name, direntry->d_name,
+ entry->path);
}
free (dlib_ptr->name);
- dlib_ptr->osversion = osversion;
dlib_ptr->name = xstrdup (direntry->d_name);
dlib_ptr->is_link = is_link;
+ dlib_ptr->osversion = osversion;
}
/* Don't add this library, abort loop. */
/* Also free soname, since it's dynamically allocated. */
@@ -906,10 +939,10 @@ search_dir (const struct dir_entry *entry)
{
dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
dlib_ptr->name = xstrdup (direntry->d_name);
- dlib_ptr->flag = flag;
- dlib_ptr->osversion = osversion;
dlib_ptr->soname = soname;
+ dlib_ptr->flag = flag;
dlib_ptr->is_link = is_link;
+ dlib_ptr->osversion = osversion;
/* Add at head of list. */
dlib_ptr->next = dlibs;
dlibs = dlib_ptr;
@@ -920,6 +953,7 @@ search_dir (const struct dir_entry *entry)
/* Now dlibs contains a list of all libs - add those to the cache
and created all symbolic links. */
+ struct dlib_entry *dlib_ptr;
for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
{
/* Don't create links to links. */
@@ -1257,7 +1291,7 @@ main (int argc, char **argv)
if (opt_chroot)
{
/* Canonicalize the directory name of cache_file, not cache_file,
- because we'll rename a temporary cache file to it. */
+ because we'll rename a temporary cache file to it. */
char *p = strrchr (cache_file, '/');
char *canon = chroot_canon (opt_chroot,
p ? (*p = '\0', cache_file) : "/");
@@ -1306,10 +1340,18 @@ main (int argc, char **argv)
add_arch_dirs (config_file);
}
+ if (! opt_ignore_aux_cache)
+ load_aux_cache (_PATH_LDCONFIG_AUX_CACHE);
+ else
+ init_aux_cache ();
+
search_dirs ();
if (opt_build_cache)
- save_cache (cache_file);
+ {
+ save_cache (cache_file);
+ save_aux_cache (_PATH_LDCONFIG_AUX_CACHE);
+ }
return 0;
}
diff --git a/elf/readelflib.c b/elf/readelflib.c
index ea92d89b20..b8f677a7b0 100644
--- a/elf/readelflib.c
+++ b/elf/readelflib.c
@@ -231,11 +231,5 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
}
}
- /* We reach this point only if the file doesn't contain a DT_SONAME
- or if we can't classify the library. If it doesn't have a
- soname, return the name of the library. */
- if (*soname == NULL)
- *soname = xstrdup (lib);
-
return 0;
}
diff --git a/elf/readlib.c b/elf/readlib.c
index a3278d935e..eb64a79f10 100644
--- a/elf/readlib.c
+++ b/elf/readlib.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2003, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -69,7 +69,7 @@ static struct known_names known_libs[] =
int
process_file (const char *real_file_name, const char *file_name,
const char *lib, int *flag, unsigned int *osversion,
- char **soname, int is_link)
+ char **soname, int is_link, struct stat64 *stat_buf)
{
FILE *file;
struct stat64 statbuf;
@@ -135,7 +135,7 @@ process_file (const char *real_file_name, const char *file_name,
)
{
/* Aout files don't have a soname, just return the name
- including the major number. */
+ including the major number. */
char *copy, *major, *dot;
copy = xstrdup (lib);
major = strstr (copy, ".so.");
@@ -175,8 +175,31 @@ process_file (const char *real_file_name, const char *file_name,
munmap (file_contents, statbuf.st_size);
fclose (file);
+ *stat_buf = statbuf;
return ret;
}
+/* Returns made up soname if lib doesn't have explicit DT_SONAME. */
+
+char *
+implicit_soname (const char *lib, int flag)
+{
+ char *soname = xstrdup (lib);
+
+ if ((flag & FLAG_TYPE_MASK) != FLAG_LIBC4)
+ return soname;
+
+ /* Aout files don't have a soname, just return the name
+ including the major number. */
+ char *major = strstr (soname, ".so.");
+ if (major)
+ {
+ char *dot = strstr (major + 4, ".");
+ if (dot)
+ *dot = '\0';
+ }
+ return soname;
+}
+
/* Get architecture specific version of process_elf_file. */
#include <readelflib.c>
diff --git a/fedora/branch.mk b/fedora/branch.mk
index ad4607637c..22e86bb507 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
glibc-base := HEAD
DIST_BRANCH := devel
COLLECTION := dist-f8
-fedora-sync-date := 2007-08-10 21:52 UTC
-fedora-sync-tag := fedora-glibc-20070810T2152
+fedora-sync-date := 2007-08-14 07:25 UTC
+fedora-sync-tag := fedora-glibc-20070814T0725
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index a696bbbe62..535cfc6a4f 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -1,4 +1,4 @@
-%define glibcrelease 7
+%define glibcrelease 9
%define run_glibc_tests 1
%define auxarches i586 i686 athlon sparcv9 alphaev6
%define xenarches i686 athlon
@@ -1000,11 +1000,17 @@ rm -f *.filelist*
%endif
%changelog
-* Fri Aug 10 2007 Roland McGrath <roland@redhat.com> 2.6.90-7
+* Tue Aug 14 2007 Jakub Jelinek <jakub@redhat.com> 2.6.90-9
+- private futex even for mutexes and condvars
+- some further O_CLOEXEC changes
+- use vDSO on x86_64 if available
+- ia64 build fixes (#251983)
+
+* Fri Aug 10 2007 Roland McGrath <roland@redhat.com> 2.6.90-8
- update to trunk
- fix missing strtold_l export on ppc64
-* Thu Aug 9 2007 Roland McGrath <roland@redhat.com> 2.6.90-5
+* Thu Aug 9 2007 Roland McGrath <roland@redhat.com> 2.6.90-6
- update to trunk
- fix local PLT regressions
- spec file revamp for new find-debuginfo.sh
diff --git a/include/stdio.h b/include/stdio.h
index 6fe881cd97..748523d4d1 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -54,12 +54,11 @@ extern int __path_search (char *__tmpl, size_t __tmpl_len,
__const char *__dir, __const char *__pfx,
int __try_tempdir);
-extern int __gen_tempname (char *__tmpl, int __kind);
+extern int __gen_tempname (char *__tmpl, int __flags, int __kind);
/* The __kind argument to __gen_tempname may be one of: */
# define __GT_FILE 0 /* create a file */
-# define __GT_BIGFILE 1 /* create a file, using open64 */
-# define __GT_DIR 2 /* create a directory */
-# define __GT_NOCREATE 3 /* just find a name not currently in use */
+# define __GT_DIR 1 /* create a directory */
+# define __GT_NOCREATE 2 /* just find a name not currently in use */
/* Print out MESSAGE on the error output and abort. */
extern void __libc_fatal (__const char *__message)
diff --git a/libio/oldtmpfile.c b/libio/oldtmpfile.c
index 8631d48c0b..d85467a392 100644
--- a/libio/oldtmpfile.c
+++ b/libio/oldtmpfile.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1993,1996-2000,2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-2000,2003,2004,2007
+ 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
@@ -38,7 +39,7 @@ __old_tmpfile (void)
if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
return NULL;
- fd = __gen_tempname (buf, __GT_FILE);
+ fd = __gen_tempname (buf, 0, __GT_FILE);
if (fd < 0)
return NULL;
diff --git a/manual/stdio.texi b/manual/stdio.texi
index 30a6e6ebe0..a39262cbc6 100644
--- a/manual/stdio.texi
+++ b/manual/stdio.texi
@@ -2456,9 +2456,8 @@ For example:
@end smallexample
@noindent
-@xref{Macro Varargs, , Macros with Variable Numbers of Arguments,
-gcc.info, Using GNU CC}, for details. But this is limited to macros,
-and does not apply to real functions at all.
+@xref{Variadic Macros,,, cpp, The C preprocessor}, for details.
+But this is limited to macros, and does not apply to real functions at all.
Before calling @code{vprintf} or the other functions listed in this
section, you @emph{must} call @code{va_start} (@pxref{Variadic
diff --git a/misc/Makefile b/misc/Makefile
index 9eac1b6275..a9709f96db 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+# Copyright (C) 1991-2006, 2007 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
@@ -45,6 +45,7 @@ routines := brk sbrk sstk ioctl \
gethostid sethostid \
revoke vhangup \
swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \
+ mkostemp mkostemp64 \
ualarm usleep \
gtty stty \
ptrace \
diff --git a/misc/Versions b/misc/Versions
index fdf2d9d2af..b182f12311 100644
--- a/misc/Versions
+++ b/misc/Versions
@@ -134,4 +134,7 @@ libc {
futimesat;
__syslog_chk; __vsyslog_chk;
}
+ GLIBC_2.7 {
+ mkostemp; mkostemp64;
+ }
}
diff --git a/misc/mkdtemp.c b/misc/mkdtemp.c
index abb9a35ceb..7cd3a44f94 100644
--- a/misc/mkdtemp.c
+++ b/misc/mkdtemp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2007 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
@@ -28,7 +28,7 @@ char *
mkdtemp (template)
char *template;
{
- if (__gen_tempname (template, __GT_DIR))
+ if (__gen_tempname (template, 0, __GT_DIR))
return NULL;
else
return template;
diff --git a/misc/mkostemp.c b/misc/mkostemp.c
new file mode 100644
index 0000000000..372e4f3c0f
--- /dev/null
+++ b/misc/mkostemp.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1998, 1999, 2001, 2007 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. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __GT_FILE
+# define __GT_FILE 0
+#endif
+
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ Then open the file and return a fd. */
+int
+mkostemp (template, flags)
+ char *template;
+ int flags;
+{
+ return __gen_tempname (template, flags, __GT_FILE);
+}
diff --git a/misc/mkostemp64.c b/misc/mkostemp64.c
new file mode 100644
index 0000000000..2ae730991e
--- /dev/null
+++ b/misc/mkostemp64.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2000, 2007 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. */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Generate a unique temporary file name from TEMPLATE.
+ The last six characters of TEMPLATE must be "XXXXXX";
+ they are replaced with a string that makes the filename unique.
+ Then open the file and return a fd. */
+int
+mkostemp64 (template, flags)
+ char *template;
+ int flags;
+{
+ return __gen_tempname (template, flags | O_LARGEFILE, __GT_FILE);
+}
diff --git a/misc/mkstemp.c b/misc/mkstemp.c
index ff0ffa2d01..d3edca0791 100644
--- a/misc/mkstemp.c
+++ b/misc/mkstemp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2001, 2007 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
@@ -31,5 +31,5 @@ int
mkstemp (template)
char *template;
{
- return __gen_tempname (template, __GT_FILE);
+ return __gen_tempname (template, 0, __GT_FILE);
}
diff --git a/misc/mkstemp64.c b/misc/mkstemp64.c
index 93c2a3ee45..400bf47d06 100644
--- a/misc/mkstemp64.c
+++ b/misc/mkstemp64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2007 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
@@ -16,6 +16,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -27,5 +28,5 @@ int
mkstemp64 (template)
char *template;
{
- return __gen_tempname (template, __GT_BIGFILE);
+ return __gen_tempname (template, O_LARGEFILE, __GT_FILE);
}
diff --git a/misc/mktemp.c b/misc/mktemp.c
index 20dfc74e5e..f600d7ea7c 100644
--- a/misc/mktemp.c
+++ b/misc/mktemp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2000, 2007 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
@@ -26,7 +26,7 @@ char *
mktemp (template)
char *template;
{
- if (__gen_tempname (template, __GT_NOCREATE) < 0)
+ if (__gen_tempname (template, 0, __GT_NOCREATE) < 0)
/* We return the null string if we can't find a unique file name. */
template[0] = '\0';
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 2e850439de..f46f53af3b 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,195 @@
+2007-08-13 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/i386/lowlevellock.h (__lll_private_flag):
+ Fix a pasto.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+ (__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or
+ FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+ Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+ (__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or
+ FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Include
+ kernel-features.h.
+ (__pthread_cond_wait, __condvar_w_cleanup): Pass LLL_PRIVATE to
+ lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is
+ process private. Switch DW_CFA_advance_loc1 and some
+ DW_CFA_advance_loc .eh_frame opcodes to DW_CFA_advance_loc4.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+ (__pthread_cond_timedwait, __condvar_tw_cleanup): Pass LLL_PRIVATE to
+ lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is
+ process private. Switch DW_CFA_advance_loc{1,2} and some
+ DW_CFA_advance_loc .eh_frame opcodes to DW_CFA_advance_loc4.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Use
+ #ifdef __ASSUME_PRIVATE_FUTEX instead of #if __ASSUME_PRIVATE_FUTEX.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+ (__pthread_cond_broadcast): Compare %r8 instead of
+ dep_mutex-cond_*(%rdi) with $-1.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+ (__pthread_cond_signal): Xor FUTEX_WAKE_OP with FUTEX_WAKE instead
+ of oring.
+
+2007-08-13 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/i386/i786/Implies: New file.
+
+2007-08-13 Jakub Jelinek <jakub@redhat.com>
+
+ * allocatestack.c: Include kernel-features.h.
+ * pthread_create.c: Likewise.
+ * pthread_mutex_init.c: Likewise.
+ * init.c: Likewise.
+ * pthread_cond_timedwait.c: Likewise.
+ * sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+ Likewise.
+ * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+ * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+
+2007-08-12 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
+ [__WORDSIZE=32] (pthread_rwlock_t): Split __flags element into four
+ byte elements. One of them is the new __shared element.
+ [__WORDSIZE=64] (pthread_rwlock_t): Renamed __pad1 element to __shared,
+ adjust names of other padding elements.
+ * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+ [__WORDSIZE=32] (pthread_rwlock_t): Split __flags element into four
+ byte elements. One of them is the new __shared element.
+ [__WORDSIZE=64] (pthread_rwlock_t): Renamed __pad1 element to __shared,
+ adjust names of other padding elements.
+ * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h (pthread_rwlock_t):
+ Renamed __pad1 element to __shared, adjust names of other padding
+ elements.
+ * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
+ (pthread_rwlock_t): Likewise.
+ * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_lock): Fix a
+ typo.
+
+2007-08-09 Anton Blanchard <anton@samba.org>
+
+ * sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c: New file.
+
+2007-08-12 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Include
+ <kernel-features.h>.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+
+2007-08-11 Ulrich Drepper <drepper@redhat.com>
+
+ * pthreadP.h (PTHREAD_ROBUST_MUTEX_PSHARED): Define.
+ * pthread_mutex_lock.c: Use it instead of PTHREAD_MUTEX_PSHARED when
+ dealing with robust mutexes.
+ * pthread_mutex_timedlock.c: Likewise.
+ * pthread_mutex_trylock.c: Likewise.
+ * pthread_mutex_unlock.c: Likewise.
+ * sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c: Likewise.
+
+2007-08-06 Jakub Jelinek <jakub@redhat.com>
+
+ * pthreadP.h (PTHREAD_MUTEX_PSHARED_BIT): Define.
+ (PTHREAD_MUTEX_TYPE): Mask __kind with 127.
+ (PTHREAD_MUTEX_PSHARED): Define.
+ * pthread_mutex_init.c (__pthread_mutex_init): Set
+ PTHREAD_MUTEX_PSHARED_BIT for pshared or robust
+ mutexes.
+ * pthread_mutex_lock.c (LLL_MUTEX_LOCK): Take mutex as argument
+ instead of its __data.__lock field, pass PTHREAD_MUTEX_PSHARED
+ as second argument to lll_lock.
+ (LLL_MUTEX_TRYLOCK): Take mutex as argument
+ instead of its __data.__lock field.
+ (LLL_ROBUST_MUTEX_LOCK): Take mutex as argument instead of its
+ __data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument
+ to lll_robust_lock.
+ (__pthread_mutex_lock): Update LLL_MUTEX_LOCK, LLL_MUTEX_TRYLOCK,
+ LLL_ROBUST_MUTEX_LOCK users, use PTHREAD_MUTEX_TYPE (mutex)
+ instead of mutex->__data.__kind directly, pass
+ PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock and lll_futex_wait.
+ * pthread_mutex_trylock.c (__pthread_mutex_trylock): Use
+ PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind
+ directly, pass PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock.
+ (pthread_mutex_timedlock): Pass PTHREAD_MUTEX_PSHARED (mutex)
+ to lll_timedlock, lll_robust_timedlock, lll_unlock and
+ lll_futex_timed_wait. Use PTHREAD_MUTEX_TYPE (mutex) instead
+ of mutex->__data.__kind directly.
+ * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Pass
+ PTHREAD_MUTEX_PSHARED (mutex) to lll_timedlock,
+ lll_robust_timedlock, lll_unlock and lll_futex_timed_wait. Use
+ PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind directly.
+ * pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt): Pass
+ PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock, lll_robust_unlock
+ and lll_futex_wake.
+ * pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling): Pass
+ PTHREAD_MUTEX_PSHARED (mutex) to lll_futex_wait and lll_futex_wake.
+ Use PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind
+ directly.
+ * sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c (LLL_MUTEX_LOCK):
+ Take mutex as argument instead of its __data.__lock field, pass
+ PTHREAD_MUTEX_PSHARED as second argument to lll_cond_lock.
+ (LLL_MUTEX_TRYLOCK): Take mutex as argument instead of its
+ __data.__lock field.
+ (LLL_ROBUST_MUTEX_LOCK): Take mutex as argument instead of its
+ __data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument
+ to lll_robust_cond_lock.
+ * pthread_cond_broadcast.c (__pthread_cond_broadcast): Add pshared
+ variable, pass it to lll_lock, lll_unlock, lll_futex_requeue and
+ lll_futex_wake. Don't use lll_futex_requeue if dependent mutex
+ has PTHREAD_MUTEX_PSHARED_BIT bit set in its __data.__kind.
+ * pthread_cond_destroy.c (__pthread_cond_destroy): Add pshared
+ variable, pass it to lll_lock, lll_unlock, lll_futex_wake and
+ lll_futex_wait.
+ * pthread_cond_signal.c (__pthread_cond_signal): Add pshared
+ variable, pass it to lll_lock, lll_unlock, lll_futex_wake_unlock and
+ lll_futex_wake.
+ * pthread_cond_timedwait.c (__pthread_cond_wait): Add
+ pshared variable, pass it to lll_lock, lll_unlock,
+ lll_futex_timedwait and lll_futex_wake.
+ * pthread_cond_wait.c (__condvar_cleanup, __pthread_cond_wait): Add
+ pshared variable, pass it to lll_lock, lll_unlock, lll_futex_wait
+ and lll_futex_wake.
+ * sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_futex_requeue,
+ lll_futex_wake_unlock): Add private argument, use __lll_private_flag
+ macro.
+ * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (lll_futex_requeue,
+ lll_futex_wake_unlock): Likewise.
+ * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (lll_futex_requeue):
+ Likewise.
+ * sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_futex_requeue,
+ lll_futex_wake_unlock): Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_futex_requeue):
+ Likewise.
+ * sysdeps/unix/sysv/linux/s390/lowlevellock.h (lll_futex_requeue,
+ lll_futex_wake_unlock): Likewise.
+ (lll_futex_wake): Fix a typo.
+ * sysdeps/unix/sysv/linux/pthread-pi-defines.sym (PS_BIT): Add.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+ (__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or
+ FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+ Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+ (__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or
+ FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+ (__pthread_cond_timedwait): Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:
+ (__condvar_cleanup, __pthread_cond_wait): Likewise.
+
2007-08-05 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h (PSEUDO):
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index f30c88f301..02a84f4d9b 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -28,6 +28,7 @@
#include <dl-sysdep.h>
#include <tls.h>
#include <lowlevellock.h>
+#include <kernel-features.h>
#ifndef NEED_SEPARATE_REGISTER_STACK
diff --git a/nptl/init.c b/nptl/init.c
index 95b9c7be5d..ffb50b4cca 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -33,6 +33,7 @@
#include <shlib-compat.h>
#include <smp.h>
#include <lowlevellock.h>
+#include <kernel-features.h>
/* Size and alignment of static TLS block. */
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 82c0f1ecf6..17b6492ad8 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -96,9 +96,22 @@ enum
PTHREAD_MUTEX_PP_ADAPTIVE_NP
= PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP
};
+#define PTHREAD_MUTEX_PSHARED_BIT 128
#define PTHREAD_MUTEX_TYPE(m) \
- ((m)->__data.__kind)
+ ((m)->__data.__kind & 127)
+
+#if LLL_PRIVATE == 0 && LLL_SHARED == 128
+# define PTHREAD_MUTEX_PSHARED(m) \
+ ((m)->__data.__kind & 128)
+#else
+# define PTHREAD_MUTEX_PSHARED(m) \
+ (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE)
+#endif
+
+/* The kernel when waking robust mutexes on exit never uses
+ FUTEX_PRIVATE_FLAG FUTEX_WAKE. */
+#define PTHREAD_ROBUST_MUTEX_PSHARED(m) LLL_SHARED
/* Ceiling in __data.__lock. __data.__lock is signed, so don't
use the MSB bit in there, but in the mask also include that bit,
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
index 5c0d76effc..22523c2973 100644
--- a/nptl/pthread_cond_broadcast.c
+++ b/nptl/pthread_cond_broadcast.c
@@ -32,8 +32,10 @@ int
__pthread_cond_broadcast (cond)
pthread_cond_t *cond;
{
+ int pshared = (cond->__data.__mutex == (void *) ~0l)
+ ? LLL_SHARED : LLL_PRIVATE;
/* Make sure we are alone. */
- lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cond->__data.__lock, pshared);
/* Are there any waiters to be woken? */
if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
@@ -47,7 +49,7 @@ __pthread_cond_broadcast (cond)
++cond->__data.__broadcast_seq;
/* We are done. */
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
/* Do not use requeue for pshared condvars. */
if (cond->__data.__mutex == (void *) ~0l)
@@ -57,21 +59,22 @@ __pthread_cond_broadcast (cond)
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
/* XXX: Kernel so far doesn't support requeue to PI futex. */
- if (__builtin_expect (mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP,
- 0))
+ /* XXX: Kernel so far can only requeue to the same type of futex,
+ in this case private (we don't requeue for pshared condvars). */
+ if (__builtin_expect (mut->__data.__kind
+ & (PTHREAD_MUTEX_PRIO_INHERIT_NP
+ | PTHREAD_MUTEX_PSHARED_BIT), 0))
goto wake_all;
/* lll_futex_requeue returns 0 for success and non-zero
for errors. */
if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
INT_MAX, &mut->__data.__lock,
- futex_val), 0))
+ futex_val, LLL_PRIVATE), 0))
{
/* The requeue functionality is not available. */
wake_all:
- lll_futex_wake (&cond->__data.__futex, INT_MAX,
- // XYZ check mutex flag
- LLL_SHARED);
+ lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
}
/* That's all. */
@@ -79,7 +82,7 @@ __pthread_cond_broadcast (cond)
}
/* We are done. */
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
return 0;
}
diff --git a/nptl/pthread_cond_destroy.c b/nptl/pthread_cond_destroy.c
index 53b5cd272f..35135a68bc 100644
--- a/nptl/pthread_cond_destroy.c
+++ b/nptl/pthread_cond_destroy.c
@@ -26,14 +26,17 @@ int
__pthread_cond_destroy (cond)
pthread_cond_t *cond;
{
+ int pshared = (cond->__data.__mutex == (void *) ~0l)
+ ? LLL_SHARED : LLL_PRIVATE;
+
/* Make sure we are alone. */
- lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cond->__data.__lock, pshared);
if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
{
/* If there are still some waiters which have not been
woken up, this is an application bug. */
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
return EBUSY;
}
@@ -60,19 +63,16 @@ __pthread_cond_destroy (cond)
{
pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
lll_futex_wake (&mut->__data.__lock, INT_MAX,
- // XYZ check mutex flag
- LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mut));
}
do
{
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
- lll_futex_wait (&cond->__data.__nwaiters, nwaiters,
- // XYZ check mutex flag
- LLL_SHARED);
+ lll_futex_wait (&cond->__data.__nwaiters, nwaiters, pshared);
- lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cond->__data.__lock, pshared);
nwaiters = cond->__data.__nwaiters;
}
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
index f2de58fa1d..023bbb5e9b 100644
--- a/nptl/pthread_cond_signal.c
+++ b/nptl/pthread_cond_signal.c
@@ -32,8 +32,11 @@ int
__pthread_cond_signal (cond)
pthread_cond_t *cond;
{
+ int pshared = (cond->__data.__mutex == (void *) ~0l)
+ ? LLL_SHARED : LLL_PRIVATE;
+
/* Make sure we are alone. */
- lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cond->__data.__lock, pshared);
/* Are there any waiters to be woken? */
if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
@@ -45,18 +48,14 @@ __pthread_cond_signal (cond)
/* Wake one. */
if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
1, &cond->__data.__lock,
- // XYZ check mutex flag
- LLL_SHARED),
- 0))
+ pshared), 0))
return 0;
- lll_futex_wake (&cond->__data.__futex, 1,
- // XYZ check mutex flag
- LLL_SHARED);
+ lll_futex_wake (&cond->__data.__futex, 1, pshared);
}
/* We are done. */
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
return 0;
}
diff --git a/nptl/pthread_cond_timedwait.c b/nptl/pthread_cond_timedwait.c
index a8d95dc224..9d268e911e 100644
--- a/nptl/pthread_cond_timedwait.c
+++ b/nptl/pthread_cond_timedwait.c
@@ -23,6 +23,7 @@
#include <lowlevellock.h>
#include <pthread.h>
#include <pthreadP.h>
+#include <kernel-features.h>
#include <shlib-compat.h>
@@ -53,14 +54,17 @@ __pthread_cond_timedwait (cond, mutex, abstime)
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
return EINVAL;
+ int pshared = (cond->__data.__mutex == (void *) ~0l)
+ ? LLL_SHARED : LLL_PRIVATE;
+
/* Make sure we are along. */
- lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cond->__data.__lock, pshared);
/* Now we can release the mutex. */
int err = __pthread_mutex_unlock_usercnt (mutex, 0);
if (err)
{
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
return err;
}
@@ -146,22 +150,20 @@ __pthread_cond_timedwait (cond, mutex, abstime)
unsigned int futex_val = cond->__data.__futex;
/* Prepare to wait. Release the condvar futex. */
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
/* Enable asynchronous cancellation. Required by the standard. */
cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */
err = lll_futex_timed_wait (&cond->__data.__futex,
- futex_val, &rt,
- // XYZ check mutex flag
- LLL_SHARED);
+ futex_val, &rt, pshared);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (cbuffer.oldtype);
/* We are going to look at shared data again, so get the lock. */
- lll_lock(cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cond->__data.__lock, pshared);
/* If a broadcast happened, we are done. */
if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
@@ -198,12 +200,10 @@ __pthread_cond_timedwait (cond, mutex, abstime)
and it can be successfully destroyed. */
if (cond->__data.__total_seq == -1ULL
&& cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
- lll_futex_wake (&cond->__data.__nwaiters, 1,
- // XYZ check mutex flag
- LLL_SHARED);
+ lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
/* We are done with the condvar. */
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
/* The cancellation handling is back to normal, remove the handler. */
__pthread_cleanup_pop (&buffer, 0);
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
index 679655f8fd..670fba5736 100644
--- a/nptl/pthread_cond_wait.c
+++ b/nptl/pthread_cond_wait.c
@@ -43,9 +43,11 @@ __condvar_cleanup (void *arg)
struct _condvar_cleanup_buffer *cbuffer =
(struct _condvar_cleanup_buffer *) arg;
unsigned int destroying;
+ int pshared = (cbuffer->cond->__data.__mutex == (void *) ~0l)
+ ? LLL_SHARED : LLL_PRIVATE;
/* We are going to modify shared data. */
- lll_lock (cbuffer->cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cbuffer->cond->__data.__lock, pshared);
if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
{
@@ -71,20 +73,16 @@ __condvar_cleanup (void *arg)
if (cbuffer->cond->__data.__total_seq == -1ULL
&& cbuffer->cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
{
- lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1,
- // XYZ check mutex flag
- LLL_SHARED);
+ lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1, pshared);
destroying = 1;
}
/* We are done. */
- lll_unlock (cbuffer->cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cbuffer->cond->__data.__lock, pshared);
/* Wake everybody to make sure no condvar signal gets lost. */
if (! destroying)
- lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX,
- // XYZ check mutex flag
- LLL_SHARED);
+ lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, pshared);
/* Get the mutex before returning unless asynchronous cancellation
is in effect. */
@@ -100,15 +98,17 @@ __pthread_cond_wait (cond, mutex)
struct _pthread_cleanup_buffer buffer;
struct _condvar_cleanup_buffer cbuffer;
int err;
+ int pshared = (cond->__data.__mutex == (void *) ~0l)
+ ? LLL_SHARED : LLL_PRIVATE;
/* Make sure we are along. */
- lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cond->__data.__lock, pshared);
/* Now we can release the mutex. */
err = __pthread_mutex_unlock_usercnt (mutex, 0);
if (__builtin_expect (err, 0))
{
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
return err;
}
@@ -144,21 +144,19 @@ __pthread_cond_wait (cond, mutex)
unsigned int futex_val = cond->__data.__futex;
/* Prepare to wait. Release the condvar futex. */
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
/* Enable asynchronous cancellation. Required by the standard. */
cbuffer.oldtype = __pthread_enable_asynccancel ();
/* Wait until woken by signal or broadcast. */
- lll_futex_wait (&cond->__data.__futex, futex_val,
- // XYZ check mutex flag
- LLL_SHARED);
+ lll_futex_wait (&cond->__data.__futex, futex_val, pshared);
/* Disable asynchronous cancellation. */
__pthread_disable_asynccancel (cbuffer.oldtype);
/* We are going to look at shared data again, so get the lock. */
- lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_lock (cond->__data.__lock, pshared);
/* If a broadcast happened, we are done. */
if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
@@ -181,12 +179,10 @@ __pthread_cond_wait (cond, mutex)
and it can be successfully destroyed. */
if (cond->__data.__total_seq == -1ULL
&& cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
- lll_futex_wake (&cond->__data.__nwaiters, 1,
- // XYZ check mutex flag
- LLL_SHARED);
+ lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
/* We are done with the condvar. */
- lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (cond->__data.__lock, pshared);
/* The cancellation handling is back to normal, remove the handler. */
__pthread_cleanup_pop (&buffer, 0);
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 3ab2fa498d..e08b76a9b8 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -27,6 +27,7 @@
#include <atomic.h>
#include <libc-internal.h>
#include <resolv.h>
+#include <kernel-features.h>
#include <shlib-compat.h>
diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
index 96f1fb00f8..d9b1ef0b98 100644
--- a/nptl/pthread_mutex_init.c
+++ b/nptl/pthread_mutex_init.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -20,6 +21,7 @@
#include <assert.h>
#include <errno.h>
#include <string.h>
+#include <kernel-features.h>
#include "pthreadP.h"
static const struct pthread_mutexattr default_attr =
@@ -120,6 +122,12 @@ __pthread_mutex_init (mutex, mutexattr)
break;
}
+ /* The kernel when waking robust mutexes on exit never uses
+ FUTEX_PRIVATE_FLAG FUTEX_WAKE. */
+ if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED
+ | PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0)
+ mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT;
+
/* Default values: mutex not used yet. */
// mutex->__count = 0; already done by memset
// mutex->__owner = 0; already done by memset
diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
index a82922e99a..ed98dfc6c3 100644
--- a/nptl/pthread_mutex_lock.c
+++ b/nptl/pthread_mutex_lock.c
@@ -27,9 +27,13 @@
#ifndef LLL_MUTEX_LOCK
-# define LLL_MUTEX_LOCK(mutex) lll_lock (mutex, /* XYZ */ LLL_SHARED)
-# define LLL_MUTEX_TRYLOCK(mutex) lll_trylock (mutex)
-# define LLL_ROBUST_MUTEX_LOCK(mutex, id) lll_robust_lock (mutex, id, /* XYZ */ LLL_SHARED)
+# define LLL_MUTEX_LOCK(mutex) \
+ lll_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
+# define LLL_MUTEX_TRYLOCK(mutex) \
+ lll_trylock ((mutex)->__data.__lock)
+# define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
+ lll_robust_lock ((mutex)->__data.__lock, id, \
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
#endif
@@ -62,7 +66,7 @@ __pthread_mutex_lock (mutex)
}
/* We have to get the mutex. */
- LLL_MUTEX_LOCK (mutex->__data.__lock);
+ LLL_MUTEX_LOCK (mutex);
assert (mutex->__data.__owner == 0);
mutex->__data.__count = 1;
@@ -79,7 +83,7 @@ __pthread_mutex_lock (mutex)
case PTHREAD_MUTEX_TIMED_NP:
simple:
/* Normal mutex. */
- LLL_MUTEX_LOCK (mutex->__data.__lock);
+ LLL_MUTEX_LOCK (mutex);
assert (mutex->__data.__owner == 0);
break;
@@ -87,7 +91,7 @@ __pthread_mutex_lock (mutex)
if (! __is_smp)
goto simple;
- if (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0)
+ if (LLL_MUTEX_TRYLOCK (mutex) != 0)
{
int cnt = 0;
int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
@@ -96,7 +100,7 @@ __pthread_mutex_lock (mutex)
{
if (cnt++ >= max_cnt)
{
- LLL_MUTEX_LOCK (mutex->__data.__lock);
+ LLL_MUTEX_LOCK (mutex);
break;
}
@@ -104,7 +108,7 @@ __pthread_mutex_lock (mutex)
BUSY_WAIT_NOP;
#endif
}
- while (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0);
+ while (LLL_MUTEX_TRYLOCK (mutex) != 0);
mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
}
@@ -166,16 +170,15 @@ __pthread_mutex_lock (mutex)
/* Check whether we already hold the mutex. */
if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
{
- if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ int kind = PTHREAD_MUTEX_TYPE (mutex);
+ if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
{
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
return EDEADLK;
}
- if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+ if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
@@ -191,14 +194,15 @@ __pthread_mutex_lock (mutex)
}
}
- oldval = LLL_ROBUST_MUTEX_LOCK (mutex->__data.__lock, id);
+ oldval = LLL_ROBUST_MUTEX_LOCK (mutex, id);
if (__builtin_expect (mutex->__data.__owner
== PTHREAD_MUTEX_NOTRECOVERABLE, 0))
{
/* This mutex is now not recoverable. */
mutex->__data.__count = 0;
- lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (mutex->__data.__lock,
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
@@ -410,8 +414,7 @@ __pthread_mutex_lock (mutex)
if (oldval != ceilval)
lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
- // XYZ check mutex flag
- LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mutex));
}
while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 2, ceilval)
diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c
index 301fb63d21..836c9a3e93 100644
--- a/nptl/pthread_mutex_setprioceiling.c
+++ b/nptl/pthread_mutex_setprioceiling.c
@@ -47,12 +47,13 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
/* Check whether we already hold the mutex. */
bool locked = false;
+ int kind = PTHREAD_MUTEX_TYPE (mutex);
if (mutex->__data.__owner == THREAD_GETMEM (THREAD_SELF, tid))
{
- if (mutex->__data.__kind == PTHREAD_MUTEX_PP_ERRORCHECK_NP)
+ if (kind == PTHREAD_MUTEX_PP_ERRORCHECK_NP)
return EDEADLK;
- if (mutex->__data.__kind == PTHREAD_MUTEX_PP_RECURSIVE_NP)
+ if (kind == PTHREAD_MUTEX_PP_RECURSIVE_NP)
locked = true;
}
@@ -81,8 +82,7 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
if (oldval != ceilval)
lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
- // XYZ check mutex flag
- LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mutex));
}
while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 2, ceilval)
@@ -113,8 +113,7 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
atomic_full_barrier ();
lll_futex_wake (&mutex->__data.__lock, INT_MAX,
- // XYZ check mutex flag
- LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mutex));
return 0;
}
diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
index 7a0ed57eaa..4bf0efea34 100644
--- a/nptl/pthread_mutex_timedlock.c
+++ b/nptl/pthread_mutex_timedlock.c
@@ -57,7 +57,7 @@ pthread_mutex_timedlock (mutex, abstime)
/* We have to get the mutex. */
result = lll_timedlock (mutex->__data.__lock, abstime,
- /* XYZ */ LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mutex));
if (result != 0)
goto out;
@@ -78,7 +78,7 @@ pthread_mutex_timedlock (mutex, abstime)
simple:
/* Normal mutex. */
result = lll_timedlock (mutex->__data.__lock, abstime,
- /* XYZ */ LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mutex));
break;
case PTHREAD_MUTEX_ADAPTIVE_NP:
@@ -95,7 +95,7 @@ pthread_mutex_timedlock (mutex, abstime)
if (cnt++ >= max_cnt)
{
result = lll_timedlock (mutex->__data.__lock, abstime,
- /* XYZ */ LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mutex));
break;
}
@@ -152,16 +152,15 @@ pthread_mutex_timedlock (mutex, abstime)
/* Check whether we already hold the mutex. */
if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
{
- if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ int kind = PTHREAD_MUTEX_TYPE (mutex);
+ if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
{
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
return EDEADLK;
}
- if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+ if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
@@ -178,14 +177,15 @@ pthread_mutex_timedlock (mutex, abstime)
}
result = lll_robust_timedlock (mutex->__data.__lock, abstime, id,
- /* XYZ */ LLL_SHARED);
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
if (__builtin_expect (mutex->__data.__owner
== PTHREAD_MUTEX_NOTRECOVERABLE, 0))
{
/* This mutex is now not recoverable. */
mutex->__data.__count = 0;
- lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (mutex->__data.__lock,
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
@@ -446,8 +446,7 @@ pthread_mutex_timedlock (mutex, abstime)
lll_futex_timed_wait (&mutex->__data.__lock,
ceilval | 2, &rt,
- // XYZ check mutex flag
- LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mutex));
}
}
while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
index 9478d382c2..f6e24d4138 100644
--- a/nptl/pthread_mutex_trylock.c
+++ b/nptl/pthread_mutex_trylock.c
@@ -115,16 +115,15 @@ __pthread_mutex_trylock (mutex)
/* Check whether we already hold the mutex. */
if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
{
- if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+ int kind = PTHREAD_MUTEX_TYPE (mutex);
+ if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
{
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
return EDEADLK;
}
- if (mutex->__data.__kind
- == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+ if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
{
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
NULL);
@@ -154,7 +153,8 @@ __pthread_mutex_trylock (mutex)
/* This mutex is now not recoverable. */
mutex->__data.__count = 0;
if (oldval == id)
- lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (mutex->__data.__lock,
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
return ENOTRECOVERABLE;
}
diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
index 6226089ebe..d33d0593d8 100644
--- a/nptl/pthread_mutex_unlock.c
+++ b/nptl/pthread_mutex_unlock.c
@@ -61,7 +61,7 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
--mutex->__data.__nusers;
/* Unlock. */
- lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
break;
case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
@@ -115,7 +115,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
--mutex->__data.__nusers;
/* Unlock. */
- lll_robust_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+ lll_robust_unlock (mutex->__data.__lock,
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
break;
@@ -242,8 +243,7 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
lll_futex_wake (&mutex->__data.__lock, 1,
- // XYZ check mutex flag
- LLL_SHARED);
+ PTHREAD_MUTEX_PSHARED (mutex));
int oldprio = newval >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
return __pthread_tpp_change_priority (oldprio, -1);
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
index 41a54d4b0d..41c0be1978 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
@@ -1,5 +1,5 @@
/* Machine-specific pthread type layouts. Alpha version.
- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 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
@@ -126,9 +126,9 @@ typedef union
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
diff --git a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
index f3f291979a..4f6796449a 100644
--- a/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
@@ -24,6 +24,7 @@
#include <bits/pthreadtypes.h>
#include <atomic.h>
#include <sysdep.h>
+#include <kernel-features.h>
#define __NR_futex 394
@@ -103,24 +104,24 @@
while (0)
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
- __ret = INTERNAL_SYSCALL (futex, __err, 6, \
- (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \
- (nr_move), (mutex), (val)); \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
})
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
- __ret = INTERNAL_SYSCALL (futex, __err, 6, \
- (futexp), FUTEX_WAKE_OP, (nr_wake), \
- (nr_wake2), (futexp2), \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
})
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
index 122d83afee..776c47f6cc 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
@@ -83,11 +83,18 @@ __pthread_cond_broadcast:
je 9f
/* XXX: The kernel so far doesn't support requeue to PI futex. */
- testl $PI_BIT, MUTEX_KIND(%edi)
+ /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same
+ type of futex (private resp. shared). */
+ testl $(PI_BIT | PS_BIT), MUTEX_KIND(%edi)
jne 9f
/* Wake up all threads. */
- movl $FUTEX_CMP_REQUEUE, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %ecx
+#else
+ movl %gs:PRIVATE_FUTEX, %ecx
+ orl $FUTEX_CMP_REQUEUE, %ecx
+#endif
movl $SYS_futex, %eax
movl $0x7fffffff, %esi
movl $1, %edx
@@ -132,28 +139,63 @@ __pthread_cond_broadcast:
#else
leal cond_lock(%ebx), %edx
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_lock_wait
jmp 2b
/* Unlock in loop requires waekup. */
5: leal cond_lock-cond_futex(%ebx), %eax
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
jmp 6b
/* Unlock in loop requires waekup. */
7: leal cond_lock-cond_futex(%ebx), %eax
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
jmp 8b
9: /* The futex requeue functionality is not available. */
movl $0x7fffffff, %edx
- movl $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
movl $SYS_futex, %eax
ENTER_KERNEL
jmp 10b
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
index e3510c8ab1..36a18036c5 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
@@ -70,7 +70,18 @@ __pthread_cond_signal:
/* Wake up one thread. */
pushl %esi
pushl %ebp
- movl $FUTEX_WAKE_OP, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE_OP, %ecx
movl $SYS_futex, %eax
movl $1, %edx
movl $1, %esi
@@ -92,7 +103,9 @@ __pthread_cond_signal:
popl %ebx
ret
-7: movl $FUTEX_WAKE, %ecx
+7: /* %ecx should be either FUTEX_WAKE_OP or
+ FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */
+ xorl $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %ecx
movl $SYS_futex, %eax
/* %edx should be 1 already from $FUTEX_WAKE_OP syscall.
movl $1, %edx */
@@ -106,8 +119,16 @@ __pthread_cond_signal:
/* Unlock in loop requires wakeup. */
5: movl %edi, %eax
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
jmp 6b
@@ -118,8 +139,16 @@ __pthread_cond_signal:
#else
leal cond_lock(%edi), %edx
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%edi)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_lock_wait
jmp 2b
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index 79a7497e8c..83f8db25bb 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -22,6 +22,7 @@
#include <lowlevellock.h>
#include <lowlevelcond.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
.text
@@ -157,7 +158,20 @@ __pthread_cond_timedwait:
movl %eax, (%esp)
leal 4(%esp), %esi
- xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+#if FUTEX_WAIT != 0
+ addl $FUTEX_WAIT, %ecx
+#endif
movl %edi, %edx
addl $cond_futex, %ebx
.Ladd_cond_futex:
@@ -231,7 +245,18 @@ __pthread_cond_timedwait:
addl $cond_nwaiters, %ebx
movl $SYS_futex, %eax
- movl $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_nwaiters(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
movl $1, %edx
ENTER_KERNEL
subl $cond_nwaiters, %ebx
@@ -279,8 +304,16 @@ __pthread_cond_timedwait:
#else
leal cond_lock(%ebx), %edx
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_lock_wait
jmp 2b
@@ -292,8 +325,16 @@ __pthread_cond_timedwait:
#else
leal cond_lock(%ebx), %eax
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
jmp 4b
@@ -304,8 +345,16 @@ __pthread_cond_timedwait:
#else
leal cond_lock(%ebx), %edx
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_lock_wait
jmp 6b
@@ -316,8 +365,16 @@ __pthread_cond_timedwait:
#else
leal cond_lock(%ebx), %eax
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
jmp 11b
@@ -338,8 +395,16 @@ __pthread_cond_timedwait:
#else
leal cond_lock(%ebx), %eax
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
movl %esi, %eax
@@ -400,8 +465,16 @@ __condvar_tw_cleanup:
#else
leal cond_lock(%ebx), %edx
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_lock_wait
1: movl broadcast_seq(%ebx), %eax
@@ -440,7 +513,18 @@ __condvar_tw_cleanup:
addl $cond_nwaiters, %ebx
movl $SYS_futex, %eax
- movl $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_nwaiters(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
movl $1, %edx
ENTER_KERNEL
subl $cond_nwaiters, %ebx
@@ -459,15 +543,34 @@ __condvar_tw_cleanup:
#else
leal cond_lock(%ebx), %eax
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
/* Wake up all waiters to make sure no signal gets lost. */
2: testl %edi, %edi
jnz 5f
addl $cond_futex, %ebx
- movl $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
movl $SYS_futex, %eax
movl $0x7fffffff, %edx
ENTER_KERNEL
@@ -587,12 +690,12 @@ __condvar_tw_cleanup:
.uleb128 20
.byte 0x83 # DW_CFA_offset %ebx
.uleb128 5
- .byte 2 # DW_CFA_advance_loc1
- .byte .Lsubl-.Lpush_ebx
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .Lsubl-.Lpush_ebx
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 20+FRAME_SIZE
- .byte 3 # DW_CFA_advance_loc2
- .2byte .Laddl-.Lsubl
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .Laddl-.Lsubl
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 20
.byte 0x40+.Lpop_ebx-.Laddl # DW_CFA_advance_loc+N
@@ -614,7 +717,8 @@ __condvar_tw_cleanup:
.byte 0x40+.LSbl1-.Lpop_edi # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 20
- .byte 0x40+.LSbl2-.LSbl1 # DW_CFA_advance_loc+N
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .LSbl2-.LSbl1
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 20+FRAME_SIZE
.byte 0x85 # DW_CFA_offset %ebp
@@ -625,14 +729,15 @@ __condvar_tw_cleanup:
.uleb128 4
.byte 0x83 # DW_CFA_offset %ebx
.uleb128 5
- .byte 0x40+.LSbl3-.LSbl2 # DW_CFA_advance_loc+N
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .LSbl3-.LSbl2
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 20
+ .byte 4 # DW_CFA_advance_loc4
#if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
- .byte 0x40+.LSbl4-.LSbl3 # DW_CFA_advance_loc+N
+ .4byte .LSbl4-.LSbl3
#else
- .byte 4 # DW_CFA_advance_loc4
- .long .LSbl5-.LSbl3
+ .4byte .LSbl5-.LSbl3
#endif
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 20+FRAME_SIZE
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index 68741bffe8..5b301979b5 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -22,6 +22,7 @@
#include <lowlevellock.h>
#include <lowlevelcond.h>
#include <tcb-offsets.h>
+#include <kernel-features.h>
.text
@@ -100,7 +101,20 @@ __pthread_cond_wait:
4: call __pthread_enable_asynccancel
movl %eax, (%esp)
- movl %esi, %ecx /* movl $FUTEX_WAIT, %ecx */
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+#if FUTEX_WAIT != 0
+ addl $FUTEX_WAIT, %ecx
+#endif
movl %edi, %edx
addl $cond_futex, %ebx
.Ladd_cond_futex:
@@ -161,7 +175,18 @@ __pthread_cond_wait:
addl $cond_nwaiters, %ebx
movl $SYS_futex, %eax
- movl $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_nwaiters(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
movl $1, %edx
ENTER_KERNEL
subl $cond_nwaiters, %ebx
@@ -197,8 +222,16 @@ __pthread_cond_wait:
#else
leal cond_lock(%ebx), %edx
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_lock_wait
jmp 2b
@@ -210,8 +243,16 @@ __pthread_cond_wait:
#else
leal cond_lock(%ebx), %eax
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
jmp 4b
@@ -222,8 +263,16 @@ __pthread_cond_wait:
#else
leal cond_lock(%ebx), %edx
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_lock_wait
jmp 6b
@@ -234,8 +283,16 @@ __pthread_cond_wait:
#else
leal cond_lock(%ebx), %eax
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
jmp 11b
@@ -256,8 +313,16 @@ __pthread_cond_wait:
#else
leal cond_lock(%ebx), %eax
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
movl %esi, %eax
@@ -292,8 +357,16 @@ __condvar_w_cleanup:
#else
leal cond_lock(%ebx), %edx
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_lock_wait
1: movl broadcast_seq(%ebx), %eax
@@ -332,7 +405,18 @@ __condvar_w_cleanup:
addl $cond_nwaiters, %ebx
movl $SYS_futex, %eax
- movl $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_nwaiters(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
movl $1, %edx
ENTER_KERNEL
subl $cond_nwaiters, %ebx
@@ -351,15 +435,34 @@ __condvar_w_cleanup:
#else
leal cond_lock(%ebx), %eax
#endif
- /* XYZ */
- movl $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex(%ebx)
+ setne %cl
+ subl $1, %ecx
+ andl $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+ addl $LLL_PRIVATE, %ecx
+#endif
call __lll_unlock_wake
/* Wake up all waiters to make sure no signal gets lost. */
2: testl %edi, %edi
jnz 5f
addl $cond_futex, %ebx
- movl $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+ xorl %ecx, %ecx
+#endif
+ cmpl $-1, dep_mutex-cond_futex(%ebx)
+ sete %cl
+ subl $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ andl $FUTEX_PRIVATE_FLAG, %ecx
+#else
+ andl %gs:PRIVATE_FUTEX, %ecx
+#endif
+ addl $FUTEX_WAKE, %ecx
movl $SYS_futex, %eax
movl $0x7fffffff, %edx
ENTER_KERNEL
@@ -473,12 +576,12 @@ __condvar_w_cleanup:
.uleb128 16
.byte 0x83 # DW_CFA_offset %ebx
.uleb128 4
- .byte 2 # DW_CFA_advance_loc1
- .byte .Lsubl-.Lpush_ebx
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .Lsubl-.Lpush_ebx
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 16+FRAME_SIZE
- .byte 2 # DW_CFA_advance_loc1
- .byte .Laddl-.Lsubl
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .Laddl-.Lsubl
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 16
.byte 0x40+ .Lpop_ebx-.Laddl # DW_CFA_advance_loc+N
@@ -502,13 +605,16 @@ __condvar_w_cleanup:
.uleb128 3
.byte 0x83 # DW_CFA_offset %ebx
.uleb128 4
- .byte 0x40+.LSbl2-.LSbl1 # DW_CFA_advance_loc+N
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .LSbl2-.LSbl1
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 16+FRAME_SIZE
- .byte 0x40+.LSbl3-.LSbl2 # DW_CFA_advance_loc+N
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .LSbl3-.LSbl2
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 16
- .byte 0x40+.LSbl4-.LSbl3 # DW_CFA_advance_loc+N
+ .byte 4 # DW_CFA_advance_loc4
+ .4byte .LSbl4-.LSbl3
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 16+FRAME_SIZE
.align 4
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
index d8a62ed2b7..d8f1bd54a2 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
@@ -21,6 +21,7 @@
#include <lowlevellock.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
.text
@@ -68,7 +69,7 @@ __pthread_rwlock_rdlock:
jne 10f
11:
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
movzbl PSHARED(%ebx), %ecx
xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
#else
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
index 71b97c60f5..0d96e03252 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
@@ -21,6 +21,7 @@
#include <lowlevellock.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
.text
@@ -99,7 +100,7 @@ pthread_rwlock_timedrdlock:
movl %edx, 4(%esp)
movl %esi, %edx
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
movzbl PSHARED(%ebp), %ecx
xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
#else
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
index c002472085..e78fdf6dda 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
@@ -21,6 +21,7 @@
#include <lowlevellock.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
.text
@@ -97,7 +98,7 @@ pthread_rwlock_timedwrlock:
movl %edx, 4(%esp)
movl %esi, %edx
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
movzbl PSHARED(%ebp), %ecx
xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
#else
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
index fdad432e30..a23e1b50a8 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
@@ -20,6 +20,7 @@
#include <sysdep.h>
#include <lowlevellock.h>
#include <lowlevelrwlock.h>
+#include <kernel-features.h>
.text
@@ -73,7 +74,7 @@ __pthread_rwlock_unlock:
jne 7f
8:
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
movzbl PSHARED(%edi), %ecx
xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx
#else
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
index 3f55c82930..65b99fe7d3 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
@@ -21,6 +21,7 @@
#include <lowlevellock.h>
#include <lowlevelrwlock.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
.text
@@ -66,7 +67,7 @@ __pthread_rwlock_wrlock:
jne 10f
11:
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
movzbl PSHARED(%ebx), %ecx
xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
#else
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i786/Implies b/nptl/sysdeps/unix/sysv/linux/i386/i786/Implies
new file mode 100644
index 0000000000..7cb7d9a678
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i786/Implies
@@ -0,0 +1,2 @@
+# The PPro and PII cores are mostly the same.
+unix/sysv/linux/i386/i686
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
index 2f663aa68b..8f67616af7 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
@@ -83,7 +83,7 @@
? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex)) \
: (fl)) \
: ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG); \
- asm ("andl %%fs:%P1, %0" : "+r" (__fl) \
+ asm ("andl %%gs:%P1, %0" : "+r" (__fl) \
: "i" (offsetof (struct pthread, header.private_futex))); \
__fl | (fl); }))
# endif
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
index 892769dca4..330717f079 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@@ -126,9 +126,9 @@ typedef union
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
index 3c28a397ea..ada79851e2 100644
--- a/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
@@ -25,6 +25,7 @@
#include <bits/pthreadtypes.h>
#include <ia64intrin.h>
#include <atomic.h>
+#include <kernel-features.h>
#define __NR_futex 1230
#define FUTEX_WAIT 0
@@ -103,18 +104,20 @@ do \
while (0)
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val, private) \
({ \
- DO_INLINE_SYSCALL(futex, 6, (long) (ftx), FUTEX_CMP_REQUEUE, \
+ DO_INLINE_SYSCALL(futex, 6, (long) (ftx), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private), \
(int) (nr_wake), (int) (nr_move), (long) (mutex), \
(int) val); \
_r10 == -1; \
})
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_wake_unlock(ftx, nr_wake, nr_wake2, ftx2) \
+#define lll_futex_wake_unlock(ftx, nr_wake, nr_wake2, ftx2, private) \
({ \
- DO_INLINE_SYSCALL(futex, 6, (long) (ftx), FUTEX_WAKE_OP, \
+ DO_INLINE_SYSCALL(futex, 6, (long) (ftx), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
(int) (nr_wake), (int) (nr_wake2), (long) (ftx2), \
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
_r10 == -1; \
@@ -152,6 +155,7 @@ extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
__lll_lock_wait_private (__futex); \
else \
__lll_lock_wait (__futex, private); \
+ } \
}))
#define lll_lock(futex, private) __lll_lock (&(futex), private)
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
index 41804d1372..80b9a4369e 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
@@ -24,6 +24,7 @@
#include <sys/param.h>
#include <bits/pthreadtypes.h>
#include <atomic.h>
+#include <kernel-features.h>
#ifndef __NR_futex
# define __NR_futex 221
@@ -107,14 +108,14 @@
while (0)
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
- __ret = INTERNAL_SYSCALL (futex, __err, 6, \
- (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \
- (nr_move), (mutex), (val)); \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
})
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c
index a7dcb2e5ff..90f2dc67c0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c
@@ -1,5 +1,5 @@
-/* ELF symbol resolve functions for VDSO objects.
- Copyright (C) 2005 Free Software Foundation, Inc.
+/* pthread_spin_unlock -- unlock a spin lock. PowerPC version.
+ Copyright (C) 2007 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
@@ -17,11 +17,13 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#ifndef _DL_VDSO_H
-#define _DL_VDSO_H 1
+#include "pthreadP.h"
+#include <lowlevellock.h>
-/* Functions for resolving symbols in the VDSO link map. */
-extern void *_dl_vdso_vsym (const char *name, const char *version)
- internal_function attribute_hidden;
-
-#endif /* dl-vdso.h */
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+ __asm __volatile (__lll_rel_instr ::: "memory");
+ *lock = 0;
+ return 0;
+}
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym b/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
index a1b6794260..d985c6a79b 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
+++ b/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
@@ -4,3 +4,4 @@
MUTEX_KIND offsetof (pthread_mutex_t, __data.__kind)
PI_BIT PTHREAD_MUTEX_PRIO_INHERIT_NP
+PS_BIT PTHREAD_MUTEX_PSHARED_BIT
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c b/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
index 81ecd6556b..93841c5b3e 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
@@ -1,8 +1,12 @@
#include <pthreadP.h>
-#define LLL_MUTEX_LOCK(mutex) lll_cond_lock (mutex, /* XYZ */ LLL_SHARED)
-#define LLL_MUTEX_TRYLOCK(mutex) lll_cond_trylock (mutex)
-#define LLL_ROBUST_MUTEX_LOCK(mutex, id) lll_robust_cond_lock (mutex, id, /* XYZ */ LLL_SHARED)
+#define LLL_MUTEX_LOCK(mutex) \
+ lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
+#define LLL_MUTEX_TRYLOCK(mutex) \
+ lll_cond_trylock ((mutex)->__data.__lock)
+#define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
+ lll_robust_cond_lock ((mutex)->__data.__lock, id, \
+ PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
#define __pthread_mutex_lock __pthread_mutex_cond_lock
#define NO_INCR
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
index c77031d7bb..c7345cd9a2 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
@@ -159,9 +159,9 @@ typedef union
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
@@ -175,9 +175,12 @@ typedef union
unsigned int __writer_wakeup;
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
- unsigned int __flags;
+ unsigned char __flags;
int __writer;
} __data;
# endif
diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
index ad4d27300f..7fee435f12 100644
--- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
@@ -24,6 +24,7 @@
#include <sys/param.h>
#include <bits/pthreadtypes.h>
#include <atomic.h>
+#include <kernel-features.h>
#define SYS_futex 238
#define FUTEX_WAIT 0
@@ -93,7 +94,7 @@
({ \
register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \
register unsigned long int __r3 asm ("3") \
- __lll_private_flag (FUTEX_WAKE, private); \
+ = __lll_private_flag (FUTEX_WAKE, private); \
register unsigned long int __r4 asm ("4") = (unsigned long int) (nr); \
register unsigned long int __result asm ("2"); \
\
@@ -117,10 +118,11 @@
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_requeue(futex, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(futex, nr_wake, nr_move, mutex, val, private) \
({ \
register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \
- register unsigned long int __r3 asm ("3") = FUTEX_CMP_REQUEUE; \
+ register unsigned long int __r3 asm ("3") \
+ = __lll_private_flag (FUTEX_CMP_REQUEUE, private); \
register unsigned long int __r4 asm ("4") = (long int) (nr_wake); \
register unsigned long int __r5 asm ("5") = (long int) (nr_move); \
register unsigned long int __r6 asm ("6") = (unsigned long int) (mutex); \
@@ -137,10 +139,11 @@
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_wake_unlock(futex, nr_wake, nr_wake2, futex2) \
+#define lll_futex_wake_unlock(futex, nr_wake, nr_wake2, futex2, private) \
({ \
register unsigned long int __r2 asm ("2") = (unsigned long int) (futex); \
- register unsigned long int __r3 asm ("3") = FUTEX_WAKE_OP; \
+ register unsigned long int __r3 asm ("3") \
+ = __lll_private_flag (FUTEX_WAKE_OP, private); \
register unsigned long int __r4 asm ("4") = (long int) (nr_wake); \
register unsigned long int __r5 asm ("5") = (long int) (nr_wake2); \
register unsigned long int __r6 asm ("6") = (unsigned long int) (futex2); \
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
index 17c1e6f567..fde4f57b2a 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
@@ -22,6 +22,7 @@
#include <lowlevelcond.h>
#include <pthread-errnos.h>
#include "lowlevel-atomic.h"
+#include <kernel-features.h>
.text
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h b/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
index e734c1205e..faf0584868 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
@@ -1,5 +1,5 @@
/* Machine-specific pthread type layouts. SPARC version.
- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@@ -160,9 +160,9 @@ typedef union
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
int __writer;
- int __pad1;
+ int __shared;
+ unsigned long int __pad1;
unsigned long int __pad2;
- unsigned long int __pad3;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
unsigned int __flags;
@@ -176,9 +176,12 @@ typedef union
unsigned int __writer_wakeup;
unsigned int __nr_readers_queued;
unsigned int __nr_writers_queued;
+ unsigned char __pad1;
+ unsigned char __pad2;
+ unsigned char __shared;
/* FLAGS must stay at this position in the structure to maintain
binary compatibility. */
- unsigned int __flags;
+ unsigned char __flags;
int __writer;
} __data;
# endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
index 38692bbd2d..f4512b2622 100644
--- a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
@@ -24,6 +24,7 @@
#include <sys/param.h>
#include <bits/pthreadtypes.h>
#include <atomic.h>
+#include <kernel-features.h>
#define FUTEX_WAIT 0
@@ -96,14 +97,14 @@
})
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
- __ret = INTERNAL_SYSCALL (futex, __err, 6, \
- (futexp), FUTEX_CMP_REQUEUE, (nr_wake), \
- (nr_move), (mutex), (val)); \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+ (nr_wake), (nr_move), (mutex), (val)); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
})
@@ -121,14 +122,14 @@
/* Avoid FUTEX_WAKE_OP if supporting pre-v9 CPUs. */
# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) 1
#else
-# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
+# define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
({ \
INTERNAL_SYSCALL_DECL (__err); \
long int __ret; \
\
- __ret = INTERNAL_SYSCALL (futex, __err, 6, \
- (futexp), FUTEX_WAKE_OP, (nr_wake), \
- (nr_wake2), (futexp2), \
+ __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \
+ __lll_private_flag (FUTEX_WAKE_OP, private), \
+ (nr_wake), (nr_wake2), (futexp2), \
FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \
INTERNAL_SYSCALL_ERROR_P (__ret, __err); \
})
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
index 192d203926..2cd69a14ce 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
@@ -533,7 +533,7 @@ LLL_STUB_UNWIND_INFO_END
while (0)
/* Returns non-zero if error happened, zero if success. */
-#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val, private) \
({ int __res; \
register int __nr_move __asm ("r10") = nr_move; \
register void *__mutex __asm ("r8") = mutex; \
@@ -541,7 +541,8 @@ LLL_STUB_UNWIND_INFO_END
__asm __volatile ("syscall" \
: "=a" (__res) \
: "0" (__NR_futex), "D" ((void *) ftx), \
- "S" (FUTEX_CMP_REQUEUE), "d" (nr_wake), \
+ "S" (__lll_private_flag (FUTEX_CMP_REQUEUE, \
+ private)), "d" (nr_wake), \
"r" (__nr_move), "r" (__mutex), "r" (__val) \
: "cx", "r11", "cc", "memory"); \
__res < 0; })
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
index 0c619bf271..6155255eb0 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
@@ -71,11 +71,18 @@ __pthread_cond_broadcast:
je 9f
/* XXX: The kernel so far doesn't support requeue to PI futex. */
- testl $PI_BIT, MUTEX_KIND(%r8)
+ /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same
+ type of futex (private resp. shared). */
+ testl $(PI_BIT | PS_BIT), MUTEX_KIND(%r8)
jne 9f
/* Wake up all threads. */
- movl $FUTEX_CMP_REQUEUE, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %esi
+#else
+ movl %fs:PRIVATE_FUTEX, %esi
+ orl $FUTEX_CMP_REQUEUE, %esi
+#endif
movl $SYS_futex, %eax
movl $1, %edx
movl $0x7fffffff, %r10d
@@ -104,8 +111,10 @@ __pthread_cond_broadcast:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_lock_wait
#if cond_lock != 0
subq $cond_lock, %rdi
@@ -114,22 +123,36 @@ __pthread_cond_broadcast:
/* Unlock in loop requires wakeup. */
5: addq $cond_lock-cond_futex, %rdi
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
jmp 6b
/* Unlock in loop requires wakeup. */
7: addq $cond_lock-cond_futex, %rdi
- /* XYZ */
+ cmpq $-1, %r8
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
subq $cond_lock-cond_futex, %rdi
jmp 8b
9: /* The futex requeue functionality is not available. */
+ cmpq $-1, %r8
movl $0x7fffffff, %edx
- movl $FUTEX_WAKE, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
movl $SYS_futex, %eax
syscall
jmp 10b
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
index 2fc9d1fad7..8f65f2cd69 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
@@ -55,10 +55,20 @@ __pthread_cond_signal:
addl $1, (%rdi)
/* Wake up one thread. */
- movl $FUTEX_WAKE_OP, %esi
- movl $SYS_futex, %eax
+ cmpq $-1, dep_mutex(%r8)
movl $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE_OP, %eax
+ movl $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE_OP, %esi
+#endif
movl $1, %r10d
+ movl $SYS_futex, %eax
#if cond_lock != 0
addq $cond_lock, %r8
#endif
@@ -75,7 +85,9 @@ __pthread_cond_signal:
xorl %eax, %eax
retq
-7: movl $FUTEX_WAKE, %esi
+7: /* %esi should be either FUTEX_WAKE_OP or
+ FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall. */
+ xorl $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %esi
movl $SYS_futex, %eax
/* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
movl $1, %edx */
@@ -98,8 +110,10 @@ __pthread_cond_signal:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_lock_wait
#if cond_lock != 0
subq $cond_lock, %rdi
@@ -109,8 +123,13 @@ __pthread_cond_signal:
/* Unlock in loop requires wakeup. */
5:
movq %r8, %rdi
- /* XYZ */
+#if cond_lock != 0
+ addq $cond_lock, %rdi
+#endif
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
jmp 6b
.size __pthread_cond_signal, .-__pthread_cond_signal
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index 003069fb6b..a5de670866 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -23,6 +23,8 @@
#include <lowlevelcond.h>
#include <pthread-errnos.h>
+#include <kernel-features.h>
+
/* For the calculation see asm/vsyscall.h. */
#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
@@ -186,12 +188,20 @@ __pthread_cond_timedwait:
movl %eax, (%rsp)
leaq 24(%rsp), %r10
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
+ cmpq $-1, dep_mutex(%rdi)
+ movq %r12, %rdx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAIT, %eax
+ movl $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
#else
- movl $FUTEX_WAIT, %esi
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+# if FUTEX_WAIT != 0
+ orl $FUTEX_WAIT, %esi
+# endif
#endif
- movq %r12, %rdx
addq $cond_futex, %rdi
movl $SYS_futex, %eax
syscall
@@ -251,9 +261,19 @@ __pthread_cond_timedwait:
jne 25f
addq $cond_nwaiters, %rdi
- movl $SYS_futex, %eax
- movl $FUTEX_WAKE, %esi
+ cmpq $-1, dep_mutex-cond_nwaiters(%rdi)
movl $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
syscall
subq $cond_nwaiters, %rdi
@@ -292,8 +312,10 @@ __pthread_cond_timedwait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_lock_wait
jmp 2b
@@ -302,8 +324,10 @@ __pthread_cond_timedwait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
jmp 4b
@@ -312,8 +336,10 @@ __pthread_cond_timedwait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_lock_wait
#if cond_lock != 0
subq $cond_lock, %rdi
@@ -325,8 +351,10 @@ __pthread_cond_timedwait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
jmp 11b
@@ -344,8 +372,10 @@ __pthread_cond_timedwait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
17: movq (%rsp), %rax
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
index 34ef2c7b77..2c17dc03a2 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -23,6 +23,8 @@
#include <lowlevelcond.h>
#include <tcb-offsets.h>
+#include <kernel-features.h>
+
.text
@@ -49,8 +51,10 @@ __condvar_cleanup:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_lock_wait
#if cond_lock != 0
subq $cond_lock, %rdi
@@ -81,9 +85,19 @@ __condvar_cleanup:
jne 4f
addq $cond_nwaiters, %rdi
- movl $SYS_futex, %eax
- movl $FUTEX_WAKE, %esi
+ cmpq $-1, dep_mutex-cond_nwaiters(%rdi)
movl $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
syscall
subq $cond_nwaiters, %rdi
movl $1, %r12d
@@ -98,16 +112,28 @@ __condvar_cleanup:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
/* Wake up all waiters to make sure no signal gets lost. */
2: testq %r12, %r12
jnz 5f
addq $cond_futex, %rdi
- movl $FUTEX_WAKE, %esi
+ cmpq $-1, dep_mutex-cond_futex(%rdi)
movl $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
movl $SYS_futex, %eax
syscall
@@ -216,12 +242,20 @@ __pthread_cond_wait:
xorq %r10, %r10
movq %r12, %rdx
addq $cond_futex-cond_lock, %rdi
- movl $SYS_futex, %eax
-#if FUTEX_WAIT == 0
- xorl %esi, %esi
+ cmpq $-1, dep_mutex-cond_futex(%rdi)
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAIT, %eax
+ movl $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
#else
- movl $FUTEX_WAIT, %esi
+ movl $FUTEX_WAIT, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+# if FUTEX_WAIT != 0
+ orl $FUTEX_WAIT, %esi
+# endif
#endif
+ movl $SYS_futex, %eax
syscall
movl (%rsp), %edi
@@ -267,9 +301,19 @@ __pthread_cond_wait:
jne 17f
addq $cond_nwaiters, %rdi
- movl $SYS_futex, %eax
- movl $FUTEX_WAKE, %esi
+ cmpq $-1, dep_mutex-cond_nwaiters(%rdi)
movl $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+ movl $FUTEX_WAKE, %eax
+ movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+ cmove %eax, %esi
+#else
+ movl $0, %eax
+ movl %fs:PRIVATE_FUTEX, %esi
+ cmove %eax, %esi
+ orl $FUTEX_WAKE, %esi
+#endif
+ movl $SYS_futex, %eax
syscall
subq $cond_nwaiters, %rdi
@@ -302,8 +346,10 @@ __pthread_cond_wait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_lock_wait
jmp 2b
@@ -312,8 +358,10 @@ __pthread_cond_wait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
jmp 4b
@@ -322,8 +370,10 @@ __pthread_cond_wait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_lock_wait
#if cond_lock != 0
subq $cond_lock, %rdi
@@ -335,8 +385,10 @@ __pthread_cond_wait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
jmp 11b
@@ -354,8 +406,10 @@ __pthread_cond_wait:
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
- /* XYZ */
+ cmpq $-1, dep_mutex-cond_lock(%rdi)
+ movl $LLL_PRIVATE, %eax
movl $LLL_SHARED, %esi
+ cmovne %eax, %esi
callq __lll_unlock_wake
13: movq %r10, %rax
diff --git a/nscd/connections.c b/nscd/connections.c
index 32a1077819..72581071af 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -469,6 +469,13 @@ fail:
}
+#ifdef O_CLOEXEC
+# define EXTRA_O_FLAGS O_CLOEXEC
+#else
+# define EXTRA_O_FLAGS 0
+#endif
+
+
/* Initialize database information structures. */
void
nscd_init (void)
@@ -491,7 +498,7 @@ nscd_init (void)
if (dbs[cnt].persistent)
{
/* Try to open the appropriate file on disk. */
- int fd = open (dbs[cnt].db_filename, O_RDWR);
+ int fd = open (dbs[cnt].db_filename, O_RDWR | EXTRA_O_FLAGS);
if (fd != -1)
{
struct stat64 st;
@@ -570,7 +577,8 @@ nscd_init (void)
/* We also need a read-only descriptor. */
if (dbs[cnt].shared)
{
- dbs[cnt].ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
+ dbs[cnt].ro_fd = open (dbs[cnt].db_filename,
+ O_RDONLY | EXTRA_O_FLAGS);
if (dbs[cnt].ro_fd == -1)
dbg_log (_("\
cannot create read-only descriptor for \"%s\"; no mmap"),
@@ -607,22 +615,23 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
if (dbs[cnt].persistent)
{
fd = open (dbs[cnt].db_filename,
- O_RDWR | O_CREAT | O_EXCL | O_TRUNC,
+ O_RDWR | O_CREAT | O_EXCL | O_TRUNC | EXTRA_O_FLAGS,
S_IRUSR | S_IWUSR);
if (fd != -1 && dbs[cnt].shared)
- ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
+ ro_fd = open (dbs[cnt].db_filename,
+ O_RDONLY | EXTRA_O_FLAGS);
}
else
{
char fname[] = _PATH_NSCD_XYZ_DB_TMP;
- fd = mkstemp (fname);
+ fd = mkostemp (fname, EXTRA_O_FLAGS);
/* We do not need the file name anymore after we
opened another file descriptor in read-only mode. */
if (fd != -1)
{
if (dbs[cnt].shared)
- ro_fd = open (fname, O_RDONLY);
+ ro_fd = open (fname, O_RDONLY | EXTRA_O_FLAGS);
unlink (fname);
}
@@ -741,6 +750,11 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
}
}
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+ /* We do not check here whether the O_CLOEXEC provided to the
+ open call was successful or not. The two fcntl calls are
+ only performed once each per process start-up and therefore
+ is not noticeable at all. */
if (paranoia
&& ((dbs[cnt].wr_fd != -1
&& fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1)
@@ -752,6 +766,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
strerror (errno));
paranoia = 0;
}
+#endif
if (dbs[cnt].head == NULL)
{
diff --git a/nscd/gai.c b/nscd/gai.c
index 23964b7fd7..f2db5299aa 100644
--- a/nscd/gai.c
+++ b/nscd/gai.c
@@ -17,6 +17,8 @@
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <alloca.h>
+#include <kernel-features.h>
+
/* This file uses the getaddrinfo code but it compiles it without NSCD
support. We just need a few symbol renames. */
#define __inet_aton inet_aton
diff --git a/nscd/servicescache.c b/nscd/servicescache.c
index 89e107bae7..d6bf51d29f 100644
--- a/nscd/servicescache.c
+++ b/nscd/servicescache.c
@@ -24,6 +24,7 @@
#include <netdb.h>
#include <unistd.h>
#include <sys/mman.h>
+#include <kernel-features.h>
#include "nscd.h"
#include "dbg_log.h"
diff --git a/nss/Makefile b/nss/Makefile
index 320fbbd9f1..f2ecadb2a7 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996,1997,1998,2000,2001,2002 Free Software Foundation, Inc.
+# Copyright (C) 1996-1998,2000,2001,2002,2007 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
@@ -62,7 +62,8 @@ subdir-dirs = $(services:%=nss_%)
vpath %.c $(subdir-dirs)
-libnss_files-routines := $(addprefix files-,$(databases))
+libnss_files-routines := $(addprefix files-,$(databases)) \
+ files-have_o_cloexec
distribute += files-XXX.c files-parse.c
diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
index fb13fbe2b6..2149d1c401 100644
--- a/nss/nss_files/files-XXX.c
+++ b/nss/nss_files/files-XXX.c
@@ -1,5 +1,5 @@
/* Common code for file-based databases in nss_files module.
- Copyright (C) 1996-1999,2001,2002,2004 Free Software Foundation, Inc.
+ Copyright (C) 1996-1999,2001,2002,2004,2007 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
@@ -24,6 +24,8 @@
#include <bits/libc-lock.h>
#include "nsswitch.h"
+#include <kernel-features.h>
+
/* These symbols are defined by the including source file:
ENTNAME -- database name of the structure and functions (hostent, pwent).
@@ -74,29 +76,44 @@ internal_setent (int stayopen)
if (stream == NULL)
{
- stream = fopen (DATAFILE, "r");
+ stream = fopen (DATAFILE, "re");
if (stream == NULL)
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
else
{
- /* We have to make sure the file is `closed on exec'. */
- int result, flags;
-
- result = flags = fcntl (fileno (stream), F_GETFD, 0);
- if (result >= 0)
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+ if (__have_o_cloexec <= 0)
+# endif
{
- flags |= FD_CLOEXEC;
- result = fcntl (fileno (stream), F_SETFD, flags);
- }
- if (result < 0)
- {
- /* Something went wrong. Close the stream and return a
- failure. */
- fclose (stream);
- stream = NULL;
- status = NSS_STATUS_UNAVAIL;
+ /* We have to make sure the file is `closed on exec'. */
+ int result;
+ int flags;
+
+ result = flags = fcntl (fileno (stream), F_GETFD, 0);
+ if (result >= 0)
+ {
+# ifdef O_CLOEXEC
+ if (__have_o_cloexec == 0)
+ __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+ if (__have_o_cloexec < 0)
+# endif
+ {
+ flags |= FD_CLOEXEC;
+ result = fcntl (fileno (stream), F_SETFD, flags);
+ }
+ }
+ if (result < 0)
+ {
+ /* Something went wrong. Close the stream and return a
+ failure. */
+ fclose (stream);
+ stream = NULL;
+ status = NSS_STATUS_UNAVAIL;
+ }
}
+#endif
}
}
else
diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
index c4717e1242..57cc982f77 100644
--- a/nss/nss_files/files-alias.c
+++ b/nss/nss_files/files-alias.c
@@ -1,5 +1,5 @@
/* Mail alias file parser in nss_files module.
- Copyright (C) 1996,97,98,99,2002,2006 Free Software Foundation, Inc.
+ Copyright (C) 1996,97,98,99,2002,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -27,6 +27,8 @@
#include <stdio.h>
#include <string.h>
+#include <kernel-features.h>
+
#include "nsswitch.h"
/* Locks the static variables in this file. */
@@ -46,29 +48,44 @@ internal_setent (void)
if (stream == NULL)
{
- stream = fopen ("/etc/aliases", "r");
+ stream = fopen ("/etc/aliases", "re");
if (stream == NULL)
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
else
{
- /* We have to make sure the file is `closed on exec'. */
- int result, flags;
-
- result = flags = fcntl (fileno (stream), F_GETFD, 0);
- if (result >= 0)
- {
- flags |= FD_CLOEXEC;
- result = fcntl (fileno (stream), F_SETFD, flags);
- }
- if (result < 0)
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+ if (__have_o_cloexec <= 0)
+# endif
{
- /* Something went wrong. Close the stream and return a
- failure. */
- fclose (stream);
- stream = NULL;
- status = NSS_STATUS_UNAVAIL;
+ /* We have to make sure the file is `closed on exec'. */
+ int result;
+ int flags;
+
+ result = flags = fcntl (fileno (stream), F_GETFD, 0);
+ if (result >= 0)
+ {
+# ifdef O_CLOEXEC
+ if (__have_o_cloexec == 0)
+ __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+ if (__have_o_cloexec < 0)
+# endif
+ {
+ flags |= FD_CLOEXEC;
+ result = fcntl (fileno (stream), F_SETFD, flags);
+ }
+ }
+ if (result < 0)
+ {
+ /* Something went wrong. Close the stream and return a
+ failure. */
+ fclose (stream);
+ stream = NULL;
+ status = NSS_STATUS_UNAVAIL;
+ }
}
+#endif
}
}
else
diff --git a/nss/nss_files/files-have_o_cloexec.c b/nss/nss_files/files-have_o_cloexec.c
new file mode 100644
index 0000000000..a83e8a4487
--- /dev/null
+++ b/nss/nss_files/files-have_o_cloexec.c
@@ -0,0 +1,24 @@
+/* Copyright (C) 2007 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. */
+
+#include <fcntl.h>
+#include <kernel-features.h>
+
+#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC
+int __have_o_cloexec;
+#endif
diff --git a/shadow/lckpwdf.c b/shadow/lckpwdf.c
index 67d9937ac2..2770fb5b33 100644
--- a/shadow/lckpwdf.c
+++ b/shadow/lckpwdf.c
@@ -1,5 +1,5 @@
/* Handle locking of password file.
- Copyright (C) 1996,98,2000,02 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1998, 2000, 2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -26,6 +26,8 @@
#include <unistd.h>
#include <sys/file.h>
+#include <kernel-features.h>
+
/* Name of the lock file. */
#define PWD_LOCKFILE "/etc/.pwd.lock"
@@ -96,20 +98,38 @@ __lckpwdf (void)
/* Prevent problems caused by multiple threads. */
__libc_lock_lock (lock);
- lock_fd = __open (PWD_LOCKFILE, O_WRONLY | O_CREAT, 0600);
+ int oflags = O_WRONLY | O_CREAT;
+#ifdef O_CLOEXEC
+ oflags |= O_CLOEXEC;
+#endif
+ lock_fd = __open (PWD_LOCKFILE, oflags, 0600);
if (lock_fd == -1)
/* Cannot create lock file. */
RETURN_CLOSE_FD (-1);
- /* Make sure file gets correctly closed when process finished. */
- flags = __fcntl (lock_fd, F_GETFD, 0);
- if (flags == -1)
- /* Cannot get file flags. */
- RETURN_CLOSE_FD (-1);
- flags |= FD_CLOEXEC; /* Close on exit. */
- if (__fcntl (lock_fd, F_SETFD, flags) < 0)
- /* Cannot set new flags. */
- RETURN_CLOSE_FD (-1);
+#ifndef __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+ if (__have_o_cloexec <= 0)
+# endif
+ {
+ /* Make sure file gets correctly closed when process finished. */
+ flags = __fcntl (lock_fd, F_GETFD, 0);
+ if (flags == -1)
+ /* Cannot get file flags. */
+ RETURN_CLOSE_FD (-1);
+# ifdef O_CLOEXEC
+ if (__have_o_cloexec == 0)
+ __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+ if (__have_o_cloexec < 0)
+# endif
+ {
+ flags |= FD_CLOEXEC; /* Close on exit. */
+ if (__fcntl (lock_fd, F_SETFD, flags) < 0)
+ /* Cannot set new flags. */
+ RETURN_CLOSE_FD (-1);
+ }
+ }
+#endif
/* Now we have to get exclusive write access. Since multiple
process could try this we won't stop when it first fails.
diff --git a/stdio-common/tempnam.c b/stdio-common/tempnam.c
index cd3dd40f90..c631d462d3 100644
--- a/stdio-common/tempnam.c
+++ b/stdio-common/tempnam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-2000,2007 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
@@ -34,7 +34,7 @@ tempnam (const char *dir, const char *pfx)
if (__path_search (buf, FILENAME_MAX, dir, pfx, 1))
return NULL;
- if (__gen_tempname (buf, __GT_NOCREATE))
+ if (__gen_tempname (buf, 0, __GT_NOCREATE))
return NULL;
return __strdup (buf);
diff --git a/stdio-common/tempname.c b/stdio-common/tempname.c
index 60c94d6409..2c7bcdee0f 100644
--- a/stdio-common/tempname.c
+++ b/stdio-common/tempname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 95-98, 99 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 95-98, 99, 2007 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
@@ -47,8 +47,9 @@ stub_warning (__path_search)
*/
int
-__gen_tempname (tmpl, kind)
+__gen_tempname (tmpl, flags, kind)
char *tmpl;
+ int flags;
int kind;
{
__set_errno (ENOSYS);
diff --git a/stdio-common/tmpfile.c b/stdio-common/tmpfile.c
index 41f12bc8ba..b90051346b 100644
--- a/stdio-common/tmpfile.c
+++ b/stdio-common/tmpfile.c
@@ -1,5 +1,6 @@
/* Open a stdio stream on an anonymous temporary file. Generic/POSIX version.
- Copyright (C) 1991,93,1996-2000,2002,2003 Free Software Foundation, Inc.
+ Copyright (C) 1991,1993,1996-2000,2002,2003,2007
+ 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
@@ -17,6 +18,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
@@ -28,9 +30,6 @@
# endif
#endif
-#ifndef GEN_THIS
-# define GEN_THIS __GT_FILE
-#endif
/* This returns a new stream opened on a temporary file (generated
by tmpnam). The file is opened with mode "w+b" (binary read/write).
@@ -45,7 +44,11 @@ tmpfile (void)
if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
return NULL;
- fd = __gen_tempname (buf, GEN_THIS);
+ int flags = 0;
+#ifdef FLAGS
+ flags = FLAGS;
+#endif
+ fd = __gen_tempname (buf, flags, __GT_FILE);
if (fd < 0)
return NULL;
@@ -59,7 +62,7 @@ tmpfile (void)
return f;
}
-#if defined USE_IN_LIBIO && GEN_THIS == __GT_FILE /* Not for tmpfile64. */
+#if defined USE_IN_LIBIO && !defined FLAGS /* Not for tmpfile64. */
# undef tmpfile
# include <shlib-compat.h>
versioned_symbol (libc, __new_tmpfile, tmpfile, GLIBC_2_1);
diff --git a/stdio-common/tmpfile64.c b/stdio-common/tmpfile64.c
index b265aeee56..ead3f50fba 100644
--- a/stdio-common/tmpfile64.c
+++ b/stdio-common/tmpfile64.c
@@ -1,3 +1,3 @@
-#define GEN_THIS __GT_BIGFILE
-#define tmpfile tmpfile64
+#define FLAGS O_LARGEFILE
+#define tmpfile tmpfile64
#include <tmpfile.c>
diff --git a/stdio-common/tmpnam.c b/stdio-common/tmpnam.c
index 6b26f4fff6..f1c16446d5 100644
--- a/stdio-common/tmpnam.c
+++ b/stdio-common/tmpnam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-1999,2000,2007 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
@@ -39,7 +39,7 @@ tmpnam (char *s)
0))
return NULL;
- if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE), 0))
+ if (__builtin_expect (__gen_tempname (tmpbuf, 0, __GT_NOCREATE), 0))
return NULL;
if (s == NULL)
diff --git a/stdio-common/tmpnam_r.c b/stdio-common/tmpnam_r.c
index 565a42401f..60c42866a7 100644
--- a/stdio-common/tmpnam_r.c
+++ b/stdio-common/tmpnam_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-1999,2000,2007 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
@@ -28,7 +28,7 @@ tmpnam_r (char *s)
if (__path_search (s, L_tmpnam, NULL, NULL, 0))
return NULL;
- if (__gen_tempname (s, __GT_NOCREATE))
+ if (__gen_tempname (s, 0, __GT_NOCREATE))
return NULL;
return s;
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index d475668926..d405cbf7b6 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -614,6 +614,28 @@ extern int mkstemp64 (char *__template) __nonnull ((1)) __wur;
extern char *mkdtemp (char *__template) __THROW __nonnull ((1)) __wur;
#endif
+#ifdef __USE_GNU
+/* Generate a unique temporary file name from TEMPLATE similar to
+ mkstemp. But allow the caller to pass additional flags which are
+ used in the open call to create the file..
+
+ This function is a possible cancellation points and therefore not
+ marked with __THROW. */
+# ifndef __USE_FILE_OFFSET64
+extern int mkostemp (char *__template, int __flags) __nonnull ((1)) __wur;
+# else
+# ifdef __REDIRECT
+extern int __REDIRECT (mkostemp, (char *__template, int __flags), mkostemp64)
+ __nonnull ((1)) __wur;
+# else
+# define mkostemp mkostemp64
+# endif
+# endif
+# ifdef __USE_LARGEFILE64
+extern int mkostemp64 (char *__template, int __flags) __nonnull ((1)) __wur;
+# endif
+#endif
+
__BEGIN_NAMESPACE_STD
/* Execute the given line as a shell command.
diff --git a/sysdeps/generic/ldconfig.h b/sysdeps/generic/ldconfig.h
index 9da8d6b3d1..fadd5ec370 100644
--- a/sysdeps/generic/ldconfig.h
+++ b/sysdeps/generic/ldconfig.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 1999.
@@ -35,6 +35,9 @@
#define FLAG_MIPS64_LIBN32 0x0600
#define FLAG_MIPS64_LIBN64 0x0700
+/* Name of auxiliary cache. */
+#define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache"
+
/* Declared in cache.c. */
extern void print_cache (const char *cache_name);
@@ -45,10 +48,24 @@ extern void save_cache (const char *cache_name);
extern void add_to_cache (const char *path, const char *lib, int flags,
unsigned int osversion, uint64_t hwcap);
+extern void init_aux_cache (void);
+
+extern void load_aux_cache (const char *aux_cache_name);
+
+extern int search_aux_cache (struct stat64 *stat_buf, int *flags,
+ unsigned int *osversion, char **soname);
+
+extern void add_to_aux_cache (struct stat64 *stat_buf, int flags,
+ unsigned int osversion, const char *soname);
+
+extern void save_aux_cache (const char *aux_cache_name);
+
/* Declared in readlib.c. */
extern int process_file (const char *real_file_name, const char *file_name,
const char *lib, int *flag, unsigned int *osversion,
- char **soname, int is_link);
+ char **soname, int is_link, struct stat64 *stat_buf);
+
+extern char *implicit_soname (const char *lib, int flag);
/* Declared in readelflib.c. */
extern int process_elf_file (const char *file_name, const char *lib, int *flag,
diff --git a/sysdeps/mach/hurd/bits/ioctls.h b/sysdeps/mach/hurd/bits/ioctls.h
index 06a73df75e..9e0b18e451 100644
--- a/sysdeps/mach/hurd/bits/ioctls.h
+++ b/sysdeps/mach/hurd/bits/ioctls.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,93,96,97,98,99,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1992,93,96,97,98,99,2001,2007 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
@@ -284,25 +284,30 @@ enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 };
#define ODDP 0x00000040 /* get/send odd parity */
#define EVENP 0x00000080 /* get/send even parity */
#define ANYP 0x000000c0 /* get any parity/send none */
-#define NLDELAY 0x00000300 /* \n delay */
+#define NLDLY 0x00000300 /* \n delay */
+#define NLDELAY NLDLY /* traditional BSD name */
#define NL0 0x00000000
#define NL1 0x00000100 /* tty 37 */
#define NL2 0x00000200 /* vt05 */
#define NL3 0x00000300
-#define TBDELAY 0x00000c00 /* horizontal tab delay */
+#define TABDLY 0x00000c00 /* horizontal tab delay */
+#define TBDELAY TABDLY /* traditional BSD name */
#define TAB0 0x00000000
#define TAB1 0x00000400 /* tty 37 */
#define TAB2 0x00000800
#define XTABS 0x00000c00 /* expand tabs on output */
-#define CRDELAY 0x00003000 /* \r delay */
+#define CRDLY 0x00003000 /* \r delay */
+#define CRDELAY CRDLY /* traditional BSD name */
#define CR0 0x00000000
#define CR1 0x00001000 /* tn 300 */
#define CR2 0x00002000 /* tty 37 */
#define CR3 0x00003000 /* concept 100 */
-#define VTDELAY 0x00004000 /* vertical tab delay */
+#define VTDLY 0x00004000 /* vertical tab delay */
+#define VTDELAY VTDLY /* traditional BSD name */
#define FF0 0x00000000
#define FF1 0x00004000 /* tty 37 */
-#define BSDELAY 0x00008000 /* \b delay */
+#define BSDLY 0x00008000 /* \b delay */
+#define BSDELAY BSDLY /* traditional BSD name */
#define BS0 0x00000000
#define BS1 0x00008000
#define ALLDELAY (NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY)
diff --git a/sysdeps/posix/tempname.c b/sysdeps/posix/tempname.c
index c8973a0852..eab658da31 100644
--- a/sysdeps/posix/tempname.c
+++ b/sysdeps/posix/tempname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2001, 2006, 2007 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
@@ -37,9 +37,8 @@
#endif
#ifndef __GT_FILE
# define __GT_FILE 0
-# define __GT_BIGFILE 1
-# define __GT_DIR 2
-# define __GT_NOCREATE 3
+# define __GT_DIR 1
+# define __GT_NOCREATE 2
#endif
#if STDC_HEADERS || _LIBC
@@ -220,12 +219,11 @@ static const char letters[] =
at the time of the call.
__GT_FILE: create the file using open(O_CREAT|O_EXCL)
and return a read-write fd. The file is mode 0600.
- __GT_BIGFILE: same as __GT_FILE but use open64().
__GT_DIR: create a directory, which will be mode 0700.
We use a clever algorithm to get hard-to-predict names. */
int
-__gen_tempname (char *tmpl, int kind)
+__gen_tempname (char *tmpl, int flags, int kind)
{
int len;
char *XXXXXX;
@@ -298,11 +296,9 @@ __gen_tempname (char *tmpl, int kind)
switch (kind)
{
case __GT_FILE:
- fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
- break;
-
- case __GT_BIGFILE:
- fd = __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+ fd = __open (tmpl,
+ (flags & ~ACCESSPERMS)
+ | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
break;
case __GT_DIR:
diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c
index a93be6349b..f3f62cf990 100644
--- a/sysdeps/unix/clock_settime.c
+++ b/sysdeps/unix/clock_settime.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2004, 2006, 2007 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
@@ -23,7 +23,7 @@
#include <ldsodefs.h>
-#if HP_TIMING_AVAIL
+#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
/* Clock frequency of the processor. We make it a 64-bit variable
because some jokers are already playing with processors with more
than 4GHz. */
@@ -33,10 +33,8 @@ static hp_timing_t freq;
/* This function is defined in the thread library. */
extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
__attribute__ ((__weak__));
-#endif
-#if HP_TIMING_AVAIL
static int
hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
{
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c
index 5afe20feb5..cd536a0fc0 100644
--- a/sysdeps/unix/sysv/linux/clock_gettime.c
+++ b/sysdeps/unix/sysv/linux/clock_gettime.c
@@ -1,5 +1,5 @@
/* clock_gettime -- Get current time from a POSIX clockid_t. Linux version.
- Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc.
+ Copyright (C) 2003,2004,2005,2006,2007 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
@@ -133,11 +133,19 @@ maybe_syscall_gettime_cpu (clockid_t clock_id, struct timespec *tp)
{
if (e == EINVAL)
{
+# ifdef HAVE_CLOCK_GETRES_VSYSCALL
/* Check whether the kernel supports CPU clocks at all.
If not, record it for the future. */
r = INTERNAL_VSYSCALL (clock_getres, err, 2,
+ MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
+ NULL);
+# else
+ /* Check whether the kernel supports CPU clocks at all.
+ If not, record it for the future. */
+ r = INTERNAL_SYSCALL (clock_getres, err, 2,
MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
NULL);
+# endif
if (INTERNAL_SYSCALL_ERROR_P (r, err))
__libc_missing_posix_cpu_timers = 1;
}
diff --git a/sysdeps/unix/sysv/linux/dl-osinfo.h b/sysdeps/unix/sysv/linux/dl-osinfo.h
index 89bad440c9..86c593ee2b 100644
--- a/sysdeps/unix/sysv/linux/dl-osinfo.h
+++ b/sysdeps/unix/sysv/linux/dl-osinfo.h
@@ -74,6 +74,7 @@ _dl_discover_osversion (void)
#define ROUND(len) (((len) + sizeof note->n_type - 1) & -sizeof note->n_type)
note = ((const void *) (note + 1)
+ ROUND (note->n_namesz) + ROUND (note->n_descsz));
+#undef ROUND
}
}
}
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c b/sysdeps/unix/sysv/linux/dl-vdso.c
index e1be097734..28d4bb1d42 100644
--- a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c
+++ b/sysdeps/unix/sysv/linux/dl-vdso.c
@@ -1,5 +1,5 @@
/* ELF symbol resolve functions for VDSO objects.
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007 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
@@ -18,13 +18,12 @@
02111-1307 USA. */
#include "config.h"
-#include <dl-hash.h>
#include <ldsodefs.h>
void *
internal_function
-_dl_vdso_vsym (const char *name, const char *version)
+_dl_vdso_vsym (const char *name, const struct r_found_version *vers)
{
struct link_map *map = GLRO (dl_sysinfo_map);
void *value = NULL;
@@ -37,19 +36,11 @@ _dl_vdso_vsym (const char *name, const char *version)
memset (&wsym, 0, sizeof (ElfW (Sym)));
wsym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE));
- /* Compute hash value to the version string. */
- struct r_found_version vers;
- vers.name = version;
- vers.hidden = 1;
- vers.hash = _dl_elf_hash (version);
- /* We don't have a specific file where the symbol can be found. */
- vers.filename = NULL;
-
/* Search the scope of the vdso map. */
const ElfW (Sym) *ref = &wsym;
lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref,
map->l_local_scope,
- &vers, 0, 0, NULL);
+ vers, 0, 0, NULL);
if (ref != NULL)
value = DL_SYMBOL_ADDRESS (result, ref);
diff --git a/sysdeps/unix/sysv/linux/dl-vdso.h b/sysdeps/unix/sysv/linux/dl-vdso.h
new file mode 100644
index 0000000000..7e433e03ab
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/dl-vdso.h
@@ -0,0 +1,49 @@
+/* ELF symbol resolve functions for VDSO objects.
+ Copyright (C) 2005, 2007 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. */
+
+#ifndef _DL_VDSO_H
+#define _DL_VDSO_H 1
+
+#include <assert.h>
+#include <ldsodefs.h>
+
+#ifdef NDEBUG
+# define CHECK_HASH(var) do {} while (0)
+#else
+# include <dl-hash.h>
+# define CHECK_HASH(var) assert (var.hash == _dl_elf_hash (var.name))
+#endif
+
+/* Create version number record for lookup. */
+#define PREPARE_VERSION(var, vname, vhash) \
+ struct r_found_version var; \
+ var.name = vname; \
+ var.hidden = 1; \
+ var.hash = vhash; \
+ CHECK_HASH (var); \
+ /* We don't have a specific file where the symbol can be found. */ \
+ var.filename = NULL
+
+
+/* Functions for resolving symbols in the VDSO link map. */
+extern void *_dl_vdso_vsym (const char *name,
+ const struct r_found_version *version)
+ internal_function attribute_hidden;
+
+#endif /* dl-vdso.h */
diff --git a/sysdeps/unix/sysv/linux/fstatfs64.c b/sysdeps/unix/sysv/linux/fstatfs64.c
index 48afd1f4d1..79c9adcdc3 100644
--- a/sysdeps/unix/sysv/linux/fstatfs64.c
+++ b/sysdeps/unix/sysv/linux/fstatfs64.c
@@ -1,5 +1,6 @@
/* Return information about the filesystem on which FD resides.
- Copyright (C) 1996,1997,1998,1999,2000,2003 Free Software Foundation, Inc.
+ Copyright (C) 1996,1997,1998,1999,2000,2003,2007
+ 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
@@ -22,6 +23,7 @@
#include <sys/statfs.h>
#include <stddef.h>
#include <sysdep.h>
+#include <kernel-features.h>
/* Defined in statfs64.c. */
extern int __no_statfs64 attribute_hidden;
diff --git a/sysdeps/unix/sysv/linux/fxstatat.c b/sysdeps/unix/sysv/linux/fxstatat.c
index c1c416abd7..1b9add40d7 100644
--- a/sysdeps/unix/sysv/linux/fxstatat.c
+++ b/sysdeps/unix/sysv/linux/fxstatat.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007 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
@@ -30,6 +30,7 @@
#include <sysdep.h>
#include <sys/syscall.h>
#include <bp-checks.h>
+#include <kernel-features.h>
#include <xstatconv.h>
diff --git a/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h b/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
index 72c60ec240..34bc3c26ab 100644
--- a/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
+++ b/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004
+/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jes Sorensen <jes@linuxcare.com>, July 2000
@@ -25,6 +25,8 @@
#ifndef _BITS_SIGCONTEXT_H
#define _BITS_SIGCONTEXT_H 1
+#define __need_size_t
+#include <stddef.h>
#include <bits/sigstack.h>
struct ia64_fpreg
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
index 66f0ac1317..6bd6bda3b0 100644
--- a/sysdeps/unix/sysv/linux/if_index.c
+++ b/sysdeps/unix/sysv/linux/if_index.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005
+/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -28,6 +28,7 @@
#include <sys/ioctl.h>
#include <bits/libc-lock.h>
#include <not-cancel.h>
+#include <kernel-features.h>
#include "netlinkaccess.h"
diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
index 02e6935538..9aa9abac3b 100644
--- a/sysdeps/unix/sysv/linux/ifaddrs.c
+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
@@ -33,6 +33,7 @@
#include <sysdep.h>
#include <time.h>
#include <unistd.h>
+#include <kernel-features.h>
#include "netlinkaccess.h"
diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
index f8116d8885..aab3df348e 100644
--- a/sysdeps/unix/sysv/linux/kernel-features.h
+++ b/sysdeps/unix/sysv/linux/kernel-features.h
@@ -428,29 +428,37 @@
# define __ASSUME_TMPFS_NAME 1
#endif
-/* pselect was introduced just after 2.6.16-rc1. Due to the way the
- kernel versions are advertised we can only rely on 2.6.17 to have
- the code. */
-#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__
+/* pselect/ppoll were introduced just after 2.6.16-rc1. Due to the way
+ the kernel versions are advertised we can only rely on 2.6.17 to have
+ the code. On x86_64 and SH this appeared first in 2.6.19-rc1,
+ on ia64 in 2.6.22-rc1 and on alpha just after 2.6.22-rc1. */
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+ && ((!defined __x86_64__ && !defined __sh__ && !defined __ia64__ \
+ && !defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020613 \
+ && (defined __x86_64__ || defined __sh__)) \
+ || (__LINUX_KERNEL_VERSION >= 0x020616 && defined __ia64__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
# define __ASSUME_PSELECT 1
-#endif
-
-/* ppoll was introduced just after 2.6.16-rc1. Due to the way the
- kernel versions are advertised we can only rely on 2.6.17 to have
- the code. */
-#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__
-# define __ASSUME_PPOLL 1
+# define __ASSUME_PPOLL 1
#endif
/* The *at syscalls were introduced just after 2.6.16-rc1. Due to the way the
kernel versions are advertised we can only rely on 2.6.17 to have
- the code. */
-#if __LINUX_KERNEL_VERSION >= 0x020611
+ the code. On PPC they were introduced in 2.6.17-rc1, on SH in 2.6.19-rc1
+ and on Alpha just after 2.6.22-rc1. */
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+ && ((!defined __sh__ && !defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020613 && defined __sh__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
# define __ASSUME_ATFCTS 1
#endif
/* Support for inter-process robust mutexes was added in 2.6.17. */
-#if __LINUX_KERNEL_VERSION >= 0x020611
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+ && ((!defined __sh__ && !defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020613 && defined __sh__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
# define __ASSUME_SET_ROBUST_LIST 1
#endif
@@ -459,8 +467,11 @@
# define __ASSUME_FUTEX_LOCK_PI 1
#endif
-/* Support for utimensat syscall was added in 2.6.22. */
-#if __LINUX_KERNEL_VERSION >= 0x020616
+/* Support for utimensat syscall was added in 2.6.22, on alpha and s390
+ only after 2.6.22-rc1. */
+#if __LINUX_KERNEL_VERSION >= 0x020616 \
+ && ((!defined __sh__ && !defined __alpha__) \
+ || __LINUX_KERNEL_VERSION >= 0x020617)
# define __ASSUME_UTIMENSAT 1
#endif
@@ -469,7 +480,10 @@
# define __ASSUME_PRIVATE_FUTEX 1
#endif
-/* Support for fallocate was added in 2.6.23. */
-#if __LINUX_KERNEL_VERSION >= 0x020617
+/* Support for fallocate was added in 2.6.23, on s390
+ only after 2.6.23-rc1. */
+#if __LINUX_KERNEL_VERSION >= 0x020617 \
+ && ((!defined __s390__ && !defined __alpha__) \
+ || (__LINUX_KERNEL_VERSION >= 0x020618 && defined __s390__))
# define __ASSUME_FALLOCATE 1
#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/Makefile b/sysdeps/unix/sysv/linux/powerpc/Makefile
index ecd8057951..d1281cf469 100644
--- a/sysdeps/unix/sysv/linux/powerpc/Makefile
+++ b/sysdeps/unix/sysv/linux/powerpc/Makefile
@@ -8,5 +8,5 @@ gen-as-const-headers += ucontext_i.sym
endif
ifeq ($(subdir),elf)
-routines += dl-vdso
+sysdep_routines += dl-vdso
endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
index f20a5a175c..746d9ced4a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
@@ -23,7 +23,7 @@
#ifdef SHARED
-extern void *__vdso_gettimeofday;
+extern void *__vdso_gettimeofday attribute_hidden;
extern void *__vdso_clock_gettime;
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
index a71cfa5b06..d1f321c44d 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
@@ -24,23 +24,6 @@
#include <bp-start.h>
#include <bp-sym.h>
-int __cache_line_size attribute_hidden;
-/* The main work is done in the generic function. */
-#define LIBC_START_MAIN generic_start_main
-#define LIBC_START_DISABLE_INLINE
-#define LIBC_START_MAIN_AUXVEC_ARG
-#define MAIN_AUXVEC_ARG
-#define INIT_MAIN_ARGS
-#include <csu/libc-start.c>
-
-struct startup_info
- {
- void *__unbounded sda_base;
- int (*main) (int, char **, char **, void *);
- int (*init) (int, char **, char **, void *);
- void (*fini) (void);
- };
-
#ifdef SHARED
# include <sys/time.h>
@@ -50,27 +33,46 @@ struct startup_info
# undef __clock_getres
# include <bits/libc-vdso.h>
-void *__vdso_gettimeofday;
+void *__vdso_gettimeofday attribute_hidden;
void *__vdso_clock_gettime;
void *__vdso_clock_getres;
void *__vdso_get_tbfreq;
-static inline void _libc_vdso_platform_setup (void)
- {
- __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday",
- "LINUX_2.6.15");
+static inline void
+_libc_vdso_platform_setup (void)
+{
+ PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
+
+ __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
- __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime",
- "LINUX_2.6.15");
+ __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2615);
- __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres",
- "LINUX_2.6.15");
+ __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615);
+
+ __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq", &linux2615);
+}
- __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq",
- "LINUX_2.6.15");
- }
+# define VDSO_SETUP _libc_vdso_platform_setup
#endif
+
+int __cache_line_size attribute_hidden;
+/* The main work is done in the generic function. */
+#define LIBC_START_MAIN generic_start_main
+#define LIBC_START_DISABLE_INLINE
+#define LIBC_START_MAIN_AUXVEC_ARG
+#define MAIN_AUXVEC_ARG
+#define INIT_MAIN_ARGS
+#include <csu/libc-start.c>
+
+struct startup_info
+ {
+ void *__unbounded sda_base;
+ int (*main) (int, char **, char **, void *);
+ int (*init) (int, char **, char **, void *);
+ void (*fini) (void);
+ };
+
int
/* GKM FIXME: GCC: this should get __BP_ prefix by virtue of the
BPs in the arglist of startup_info.main and startup_info.init. */
@@ -117,10 +119,7 @@ int
__cache_line_size = av->a_un.a_val;
break;
}
-#ifdef SHARED
- /* Resolve and initialize function pointers for VDSO functions. */
- _libc_vdso_platform_setup ();
-#endif
+
return generic_start_main (stinfo->main, argc, ubp_av, auxvec,
stinfo->init, stinfo->fini, rtld_fini,
stack_on_entry);
diff --git a/sysdeps/unix/sysv/linux/ppoll.c b/sysdeps/unix/sysv/linux/ppoll.c
index cfc86ba806..14eb3111b9 100644
--- a/sysdeps/unix/sysv/linux/ppoll.c
+++ b/sysdeps/unix/sysv/linux/ppoll.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
@@ -26,9 +26,11 @@
#ifdef __NR_ppoll
+# ifndef __ASSUME_PPOLL
static int __generic_ppoll (struct pollfd *fds, nfds_t nfds,
const struct timespec *timeout,
const sigset_t *sigmask);
+# endif
int
diff --git a/sysdeps/unix/sysv/linux/pselect.c b/sysdeps/unix/sysv/linux/pselect.c
index 0dd744f527..f39ee920cd 100644
--- a/sysdeps/unix/sysv/linux/pselect.c
+++ b/sysdeps/unix/sysv/linux/pselect.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
@@ -26,10 +26,12 @@
#ifdef __NR_pselect6
+# ifndef __ASSUME_PSELECT
static int __generic_pselect (int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds,
const struct timespec *timeout,
const sigset_t *sigmask);
+# endif
int
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S b/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
index c0d7cd4590..b2db5423c3 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <kernel-features.h>
#define EINVAL 22
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S b/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
index aba4ac34e3..4c3667aaa5 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <kernel-features.h>
#define EINVAL 22
#define ENOSYS 38
diff --git a/sysdeps/unix/sysv/linux/shm_open.c b/sysdeps/unix/sysv/linux/shm_open.c
index 0628427680..92d22cfa76 100644
--- a/sysdeps/unix/sysv/linux/shm_open.c
+++ b/sysdeps/unix/sysv/linux/shm_open.c
@@ -187,7 +187,7 @@ shm_open (const char *name, int oflag, mode_t mode)
if (__builtin_expect (flags, 0) >= 0)
{
-# ifndef O_CLOEXEC
+# ifdef O_CLOEXEC
if (have_o_cloexec == 0)
have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
if (have_o_cloexec < 0)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c b/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
index 9f4c02c78b..71a51ccd8a 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
@@ -1,3 +1,5 @@
+#include <kernel-features.h>
+
#include "../../i386/xstat.c"
#ifdef __NR_stat64
diff --git a/sysdeps/unix/sysv/linux/statfs64.c b/sysdeps/unix/sysv/linux/statfs64.c
index 9ccc7a7d69..c3d17b5edd 100644
--- a/sysdeps/unix/sysv/linux/statfs64.c
+++ b/sysdeps/unix/sysv/linux/statfs64.c
@@ -1,5 +1,5 @@
/* Return information about the filesystem on which FILE resides.
- Copyright (C) 1996-2000,2003,2004 Free Software Foundation, Inc.
+ Copyright (C) 1996-2000,2003,2004,2007 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
@@ -22,6 +22,7 @@
#include <sys/statfs.h>
#include <stddef.h>
#include <sysdep.h>
+#include <kernel-features.h>
# if __ASSUME_STATFS64 == 0
diff --git a/sysdeps/unix/sysv/linux/x86_64/Makefile b/sysdeps/unix/sysv/linux/x86_64/Makefile
index bdad5063df..6e2741a967 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Makefile
+++ b/sysdeps/unix/sysv/linux/x86_64/Makefile
@@ -13,3 +13,7 @@ endif
ifeq ($(subdir),csu)
gen-as-const-headers += ucontext_i.sym
endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
diff --git a/sysdeps/unix/sysv/linux/x86_64/Versions b/sysdeps/unix/sysv/linux/x86_64/Versions
index fd1b3cc296..34c100bfd2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/Versions
+++ b/sysdeps/unix/sysv/linux/x86_64/Versions
@@ -6,4 +6,7 @@ libc {
modify_ldt;
}
+ GLIBC_PRIVATE {
+ __vdso_clock_gettime;
+ }
}
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
new file mode 100644
index 0000000000..6e08d3b203
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
@@ -0,0 +1,35 @@
+/* Resolve function pointers to VDSO functions.
+ Copyright (C) 2005, 2007 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. */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern int (*__vdso_gettimeofday) (struct timeval *, void *)
+ attribute_hidden;
+
+extern int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
index 84a99b0406..f618e738b1 100644
--- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
+++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2007 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
@@ -28,7 +28,12 @@ ENTRY (__gettimeofday)
/* Align stack. */
sub $0x8, %rsp
cfi_adjust_cfa_offset(8)
+#ifdef SHARED
+ movq __vdso_gettimeofday(%rip), %rax
+ PTR_DEMANGLE (%rax)
+#else
movq $VSYSCALL_ADDR_vgettimeofday, %rax
+#endif
callq *%rax
/* Check error return. */
cmpl $-4095, %eax
diff --git a/sysdeps/unix/sysv/linux/x86_64/libc-start.c b/sysdeps/unix/sysv/linux/x86_64/libc-start.c
new file mode 100644
index 0000000000..dea2e8afe4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/libc-start.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 2007 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. */
+
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <bits/libc-vdso.h>
+
+int (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden;
+
+int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+
+static inline void
+_libc_vdso_platform_setup (void)
+{
+ PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+ void *p = _dl_vdso_vsym ("gettimeofday", &linux26);
+ /* If the vDSO is not available we fall back on the old vsyscall. */
+#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000ul
+ if (p == NULL)
+ p = (void *) VSYSCALL_ADDR_vgettimeofday;
+ PTR_MANGLE (p);
+ __vdso_gettimeofday = p;
+
+ p = _dl_vdso_vsym ("clock_gettime", &linux26);
+ PTR_MANGLE (p);
+ __vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP _libc_vdso_platform_setup
+#endif
+
+#include <csu/libc-start.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
index 1d9a68a046..44d5650549 100644
--- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h
@@ -68,14 +68,14 @@
/* We don't want the label for the error handle to be global when we define
it here. */
-#ifdef PIC
-# define SYSCALL_ERROR_LABEL 0f
-#else
-# define SYSCALL_ERROR_LABEL syscall_error
-#endif
+# ifdef PIC
+# define SYSCALL_ERROR_LABEL 0f
+# else
+# define SYSCALL_ERROR_LABEL syscall_error
+# endif
-#undef PSEUDO
-#define PSEUDO(name, syscall_name, args) \
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (syscall_name, args); \
@@ -83,40 +83,40 @@
jae SYSCALL_ERROR_LABEL; \
L(pseudo_end):
-#undef PSEUDO_END
-#define PSEUDO_END(name) \
+# undef PSEUDO_END
+# define PSEUDO_END(name) \
SYSCALL_ERROR_HANDLER \
END (name)
-#undef PSEUDO_NOERRNO
-#define PSEUDO_NOERRNO(name, syscall_name, args) \
+# undef PSEUDO_NOERRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (syscall_name, args)
-#undef PSEUDO_END_NOERRNO
-#define PSEUDO_END_NOERRNO(name) \
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name) \
END (name)
-#define ret_NOERRNO ret
+# define ret_NOERRNO ret
-#undef PSEUDO_ERRVAL
-#define PSEUDO_ERRVAL(name, syscall_name, args) \
+# undef PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args) \
.text; \
ENTRY (name) \
DO_CALL (syscall_name, args); \
negq %rax
-#undef PSEUDO_END_ERRVAL
-#define PSEUDO_END_ERRVAL(name) \
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) \
END (name)
-#define ret_ERRVAL ret
+# define ret_ERRVAL ret
-#ifndef PIC
-#define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
-#elif RTLD_PRIVATE_ERRNO
-# define SYSCALL_ERROR_HANDLER \
+# ifndef PIC
+# define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */
+# elif RTLD_PRIVATE_ERRNO
+# define SYSCALL_ERROR_HANDLER \
0: \
leaq rtld_errno(%rip), %rcx; \
xorl %edx, %edx; \
@@ -124,13 +124,13 @@
movl %edx, (%rcx); \
orq $-1, %rax; \
jmp L(pseudo_end);
-#elif USE___THREAD
-# ifndef NOT_IN_libc
-# define SYSCALL_ERROR_ERRNO __libc_errno
-# else
-# define SYSCALL_ERROR_ERRNO errno
-# endif
-# define SYSCALL_ERROR_HANDLER \
+# elif USE___THREAD
+# ifndef NOT_IN_libc
+# define SYSCALL_ERROR_ERRNO __libc_errno
+# else
+# define SYSCALL_ERROR_ERRNO errno
+# endif
+# define SYSCALL_ERROR_HANDLER \
0: \
movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\
xorl %edx, %edx; \
@@ -138,10 +138,10 @@
movl %edx, %fs:(%rcx); \
orq $-1, %rax; \
jmp L(pseudo_end);
-#elif defined _LIBC_REENTRANT
+# elif defined _LIBC_REENTRANT
/* Store (- %rax) into errno through the GOT.
Note that errno occupies only 4 bytes. */
-# define SYSCALL_ERROR_HANDLER \
+# define SYSCALL_ERROR_HANDLER \
0: \
xorl %edx, %edx; \
subq %rax, %rdx; \
@@ -158,15 +158,15 @@
/* A quick note: it is assumed that the call to `__errno_location' does
not modify the stack! */
-#else /* Not _LIBC_REENTRANT. */
-# define SYSCALL_ERROR_HANDLER \
+# else /* Not _LIBC_REENTRANT. */
+# define SYSCALL_ERROR_HANDLER \
0:movq errno@GOTPCREL(%RIP), %rcx; \
xorl %edx, %edx; \
subq %rax, %rdx; \
movl %edx, (%rcx); \
orq $-1, %rax; \
jmp L(pseudo_end);
-#endif /* PIC */
+# endif /* PIC */
/* The Linux/x86-64 kernel expects the system call parameters in
registers according to the following table:
@@ -204,25 +204,25 @@
Syscalls of more than 6 arguments are not supported. */
-#undef DO_CALL
-#define DO_CALL(syscall_name, args) \
+# undef DO_CALL
+# define DO_CALL(syscall_name, args) \
DOARGS_##args \
movl $SYS_ify (syscall_name), %eax; \
syscall;
-#define DOARGS_0 /* nothing */
-#define DOARGS_1 /* nothing */
-#define DOARGS_2 /* nothing */
-#define DOARGS_3 /* nothing */
-#define DOARGS_4 movq %rcx, %r10;
-#define DOARGS_5 DOARGS_4
-#define DOARGS_6 DOARGS_5
+# define DOARGS_0 /* nothing */
+# define DOARGS_1 /* nothing */
+# define DOARGS_2 /* nothing */
+# define DOARGS_3 /* nothing */
+# define DOARGS_4 movq %rcx, %r10;
+# define DOARGS_5 DOARGS_4
+# define DOARGS_6 DOARGS_5
#else /* !__ASSEMBLER__ */
/* Define a macro which expands inline into the wrapper code for a system
call. */
-#undef INLINE_SYSCALL
-#define INLINE_SYSCALL(name, nr, args...) \
+# undef INLINE_SYSCALL
+# define INLINE_SYSCALL(name, nr, args...) \
({ \
unsigned long resultvar = INTERNAL_SYSCALL (name, , nr, args); \
if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \
@@ -232,10 +232,10 @@
} \
(long) resultvar; })
-#undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+# undef INTERNAL_SYSCALL_DECL
+# define INTERNAL_SYSCALL_DECL(err) do { } while (0)
-#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
({ \
unsigned long resultvar; \
LOAD_ARGS_##nr (args) \
@@ -245,68 +245,126 @@
: "=a" (resultvar) \
: "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \
(long) resultvar; })
-#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
+# undef INTERNAL_SYSCALL
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
-#undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+# undef INTERNAL_SYSCALL_ERROR_P
+# define INTERNAL_SYSCALL_ERROR_P(val, err) \
((unsigned long) (val) >= -4095L)
-#undef INTERNAL_SYSCALL_ERRNO
-#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+# undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+
+# ifdef SHARED
+# define INLINE_VSYSCALL(name, nr, args...) \
+ ({ \
+ __label__ out; \
+ __label__ iserr; \
+ INTERNAL_SYSCALL_DECL (sc_err); \
+ long int sc_ret; \
+ \
+ __typeof (__vdso_##name) vdsop = __vdso_##name; \
+ PTR_DEMANGLE (vdsop); \
+ if (vdsop != NULL) \
+ { \
+ sc_ret = vdsop (args); \
+ if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ goto out; \
+ if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS) \
+ goto iserr; \
+ } \
+ \
+ sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args); \
+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ { \
+ iserr: \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
+ sc_ret = -1L; \
+ } \
+ out: \
+ sc_ret; \
+ })
+# define INTERNAL_VSYSCALL(name, err, nr, args...) \
+ ({ \
+ __label__ out; \
+ long int v_ret; \
+ \
+ __typeof (__vdso_##name) vdsop = __vdso_##name; \
+ PTR_DEMANGLE (vdsop); \
+ if (vdsop != NULL) \
+ { \
+ v_ret = vdsop (args); \
+ if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err) \
+ || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS) \
+ goto out; \
+ } \
+ v_ret = INTERNAL_SYSCALL (name, err, nr, ##args); \
+ out: \
+ v_ret; \
+ })
+
+/* List of system calls which are supported as vsyscalls. */
+# define HAVE_CLOCK_GETTIME_VSYSCALL 1
+
+# else
+# define INLINE_VSYSCALL(name, nr, args...) \
+ INLINE_SYSCALL (name, nr, ##args)
+# define INTERNAL_VSYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL (name, err, nr, ##args)
+# endif
-#define LOAD_ARGS_0()
-#define LOAD_REGS_0
-#define ASM_ARGS_0
+# define LOAD_ARGS_0()
+# define LOAD_REGS_0
+# define ASM_ARGS_0
-#define LOAD_ARGS_1(a1) \
+# define LOAD_ARGS_1(a1) \
long int __arg1 = (long) (a1); \
LOAD_ARGS_0 ()
-#define LOAD_REGS_1 \
+# define LOAD_REGS_1 \
register long int _a1 asm ("rdi") = __arg1; \
LOAD_REGS_0
-#define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
+# define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
-#define LOAD_ARGS_2(a1, a2) \
+# define LOAD_ARGS_2(a1, a2) \
long int __arg2 = (long) (a2); \
LOAD_ARGS_1 (a1)
-#define LOAD_REGS_2 \
+# define LOAD_REGS_2 \
register long int _a2 asm ("rsi") = __arg2; \
LOAD_REGS_1
-#define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
+# define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
-#define LOAD_ARGS_3(a1, a2, a3) \
+# define LOAD_ARGS_3(a1, a2, a3) \
long int __arg3 = (long) (a3); \
LOAD_ARGS_2 (a1, a2)
-#define LOAD_REGS_3 \
+# define LOAD_REGS_3 \
register long int _a3 asm ("rdx") = __arg3; \
LOAD_REGS_2
-#define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
+# define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
-#define LOAD_ARGS_4(a1, a2, a3, a4) \
+# define LOAD_ARGS_4(a1, a2, a3, a4) \
long int __arg4 = (long) (a4); \
LOAD_ARGS_3 (a1, a2, a3)
-#define LOAD_REGS_4 \
+# define LOAD_REGS_4 \
register long int _a4 asm ("r10") = __arg4; \
LOAD_REGS_3
-#define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
+# define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
-#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
+# define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
long int __arg5 = (long) (a5); \
LOAD_ARGS_4 (a1, a2, a3, a4)
-#define LOAD_REGS_5 \
+# define LOAD_REGS_5 \
register long int _a5 asm ("r8") = __arg5; \
LOAD_REGS_4
-#define ASM_ARGS_5 ASM_ARGS_4, "r" (_a5)
+# define ASM_ARGS_5 ASM_ARGS_4, "r" (_a5)
-#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
+# define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
long int __arg6 = (long) (a6); \
LOAD_ARGS_5 (a1, a2, a3, a4, a5)
-#define LOAD_REGS_6 \
+# define LOAD_REGS_6 \
register long int _a6 asm ("r9") = __arg6; \
LOAD_REGS_5
-#define ASM_ARGS_6 ASM_ARGS_5, "r" (_a6)
+# define ASM_ARGS_6 ASM_ARGS_5, "r" (_a6)
#endif /* __ASSEMBLER__ */
diff --git a/sysdeps/unix/sysv/linux/xstatconv.c b/sysdeps/unix/sysv/linux/xstatconv.c
index 805e339782..8210798a69 100644
--- a/sysdeps/unix/sysv/linux/xstatconv.c
+++ b/sysdeps/unix/sysv/linux/xstatconv.c
@@ -1,5 +1,6 @@
/* Convert between the kernel's `struct stat' format, and libc's.
- Copyright (C) 1991,1995-1997,2000,2002,2003 Free Software Foundation, Inc.
+ Copyright (C) 1991,1995-1997,2000,2002,2003,2007
+ 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
@@ -20,6 +21,7 @@
#include <errno.h>
#include <sys/stat.h>
#include <kernel_stat.h>
+#include <kernel-features.h>
#ifdef STAT_IS_KERNEL_STAT